package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.xbongbong.formula.constant.Constant;
import com.xbongbong.paas.constant.ConfigConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasListGroupEntity;
import com.xbongbong.paas.domain.entity.PaasProcessDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.DefaultTypeEnum;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.enums.ScreenTypeEnum;
import com.xbongbong.paas.field.BusinessFieldPojo;
import com.xbongbong.paas.field.DefaultAttrPoJo;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.FormulaPoJo;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.NumericalLimitsPoJo;
import com.xbongbong.sys.help.PackageHelp;
import com.xbongbong.paas.model.FineClueCompanyModel;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.model.PaasListGroupModel;
import com.xbongbong.paas.model.PaasProcessDataModel;
import com.xbongbong.paas.model.SearchCustomerCompanyModel;
import com.xbongbong.paas.pojo.dto.FixDataJobDTO;
import com.xbongbong.paas.pojo.dto.FormExplainAddDTO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisConstant;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.service.OperateLogService;
import com.xbongbong.paas.service.PaasFormExplainService;
import com.xbongbong.paas.service.abstracts.AbstractPaasRepairExplainService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.CommentUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.contract.pojo.dto.ContractUpdateBatchDTO;
import com.xbongbong.pro.contract.pojo.dto.ContractUpdateDTO;
import com.xbongbong.pro.detailtab.pojo.TabConfigPojo;
import com.xbongbong.pro.domain.entity.DetailTabConfigEntity;
import com.xbongbong.pro.domain.entity.SearchCustomerCompanyEntity;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.BusinessFineClueEnum;
import com.xbongbong.pro.enums.DistributorMarkEnum;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.FineClueMatchSearchEnum;
import com.xbongbong.pro.enums.PackageTypeEnum;
import com.xbongbong.pro.enums.RepairExplainEnum;
import com.xbongbong.pro.enums.SoukeMealEnum;
import com.xbongbong.pro.enums.errorcodes.BusinessTypeErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.TemplateErrorCodeEnum;
import com.xbongbong.pro.formexplain.pojo.dto.FormExplainAddBatchDTO;
import com.xbongbong.pro.formexplain.pojo.vo.FormExplainAddBatchVO;
import com.xbongbong.pro.fundset.pojo.FundSetTransitionPojo;
import com.xbongbong.pro.log.pojo.DetailLogDataPojo;
import com.xbongbong.pro.log.pojo.dto.OperateDetailLogDTO;
import com.xbongbong.pro.log.pojo.dto.OperateLogListDTO;
import com.xbongbong.pro.log.pojo.vo.OperateDetailLogVO;
import com.xbongbong.pro.log.pojo.vo.OperateLogListVO;
import com.xbongbong.pro.log.pojo.vo.OperateLogVO;
import com.xbongbong.pro.payment.pojo.dto.PaymentUpdateBatchDTO;
import com.xbongbong.pro.payment.pojo.dto.PaymentUpdateDTO;
import com.xbongbong.pro.script.pojo.dto.AllScriptDTO;
import com.xbongbong.pro.script.pojo.dto.FieldSetDTO;
import com.xbongbong.pro.script.pojo.dto.FixContractDTO;
import com.xbongbong.pro.script.pojo.dto.FixFormDTO;
import com.xbongbong.pro.script.pojo.dto.RepairContractBadAmountDTO;
import com.xbongbong.pro.script.pojo.dto.RepairContractDataDTO;
import com.xbongbong.pro.script.pojo.dto.RepairContractPerformanceDataDTO;
import com.xbongbong.pro.script.pojo.dto.RepairDepartmentIdBecauseApiDTO;
import com.xbongbong.pro.script.pojo.dto.RepairInvoiceAmountDTO;
import com.xbongbong.pro.script.pojo.dto.RepairInvoiceRelationMoneyDTO;
import com.xbongbong.pro.script.pojo.dto.SyncContactUserDTO;
import com.xbongbong.pro.script.pojo.dto.SyncPaymentUserDTO;
import com.xbongbong.pro.script.pojo.dto.UpdateFundManagemenExpalinstDTO;
import com.xbongbong.pro.script.pojo.dto.UpdatePaymentDataDTO;
import com.xbongbong.pro.script.pojo.dto.UpdatePaymentExplainsDTO;
import com.xbongbong.pro.script.pojo.dto.UpdateTabDTO;
import com.xbongbong.pro.script.pojo.vo.ScriptVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.ContactUserEntity;
import com.xbongbong.saas.domain.entity.ContractPerformanceEntity;
import com.xbongbong.saas.domain.entity.ContractUserEntity;
import com.xbongbong.saas.domain.entity.CustomerUserEntity;
import com.xbongbong.saas.domain.entity.FundAccountEntity;
import com.xbongbong.saas.domain.entity.InvoiceRelationshipEntity;
import com.xbongbong.saas.domain.entity.PaymentUserEntity;
import com.xbongbong.saas.domain.entity.PurchaseInvoiceRelationshipEntity;
import com.xbongbong.saas.domain.entity.WorkOrderExplainEntity;
import com.xbongbong.saas.domain.entity.ext.ContactEntityExt;
import com.xbongbong.saas.domain.entity.ext.ContractEntityExt;
import com.xbongbong.saas.domain.entity.ext.InvoiceEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentSheetEntityExt;
import com.xbongbong.saas.domain.entity.ext.PurchaseInvoiceEntityExt;
import com.xbongbong.saas.enums.BusinessDetailTabEnum;
import com.xbongbong.saas.enums.CompanyConfigEnum;
import com.xbongbong.saas.enums.ForbiddenSettingEnum;
import com.xbongbong.saas.enums.ListGroupEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.SheetAloneEnum;
import com.xbongbong.saas.enums.ShowTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.AssembleEnum;
import com.xbongbong.saas.enums.business.BadDebtEnum;
import com.xbongbong.saas.enums.business.BatchFlowBillEnum;
import com.xbongbong.saas.enums.business.BomBillEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.CommunicatePlanEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.ContractEnum;
import com.xbongbong.saas.enums.business.ContractOutstockEnum;
import com.xbongbong.saas.enums.business.CustomerCommunicateEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.FundTransferEnum;
import com.xbongbong.saas.enums.business.InstockEnum;
import com.xbongbong.saas.enums.business.InventoryEnum;
import com.xbongbong.saas.enums.business.InvoiceEnum;
import com.xbongbong.saas.enums.business.MarketActivityEnum;
import com.xbongbong.saas.enums.business.OriStockEnum;
import com.xbongbong.saas.enums.business.OtherExpenseEnum;
import com.xbongbong.saas.enums.business.OtherIncomeEnum;
import com.xbongbong.saas.enums.business.OutstockEnum;
import com.xbongbong.saas.enums.business.PayPlanEnum;
import com.xbongbong.saas.enums.business.PaySheetEnum;
import com.xbongbong.saas.enums.business.PaymentEnum;
import com.xbongbong.saas.enums.business.PaymentRelationshipEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.enums.business.PaymentTaskEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.ProductionInstockEnum;
import com.xbongbong.saas.enums.business.ProductionMaterielOutstockEnum;
import com.xbongbong.saas.enums.business.ProductionOrderEnum;
import com.xbongbong.saas.enums.business.PurchaseEnum;
import com.xbongbong.saas.enums.business.PurchaseInstockEnum;
import com.xbongbong.saas.enums.business.PurchaseInvoiceEnum;
import com.xbongbong.saas.enums.business.PushNotifyEnum;
import com.xbongbong.saas.enums.business.QuotationEnum;
import com.xbongbong.saas.enums.business.RedPaymentSheetEnum;
import com.xbongbong.saas.enums.business.RefundEnum;
import com.xbongbong.saas.enums.business.RefundInstockEnum;
import com.xbongbong.saas.enums.business.ReturnedMaterielInstockEnum;
import com.xbongbong.saas.enums.business.ReturnedPurchaseEnum;
import com.xbongbong.saas.enums.business.ReturnedPurchaseOutstockEnum;
import com.xbongbong.saas.enums.business.SalesOpportunityEnum;
import com.xbongbong.saas.enums.business.StockProductEnum;
import com.xbongbong.saas.enums.business.SupplierCommunicateEnum;
import com.xbongbong.saas.enums.business.SupplierContactEnum;
import com.xbongbong.saas.enums.business.SupplierEnum;
import com.xbongbong.saas.enums.business.TransferEnum;
import com.xbongbong.saas.enums.business.WarehouseEnum;
import com.xbongbong.saas.enums.business.WorkOrderEnum;
import com.xbongbong.saas.enums.business.WorkOrderOutstockEnum;
import com.xbongbong.saas.enums.business.WorkReportDailyEnum;
import com.xbongbong.saas.enums.business.WorkReportMonthlyEnum;
import com.xbongbong.saas.enums.business.WorkReportWeeklyEnum;
import com.xbongbong.saas.enums.dictionary.PaymentStatusEnum;
import com.xbongbong.saas.enums.product.ContractOutstockProductEnum;
import com.xbongbong.saas.enums.product.ContractProductEnum;
import com.xbongbong.saas.enums.product.InstockProductEnum;
import com.xbongbong.saas.enums.product.InventoryProductEnum;
import com.xbongbong.saas.enums.product.OpportunityProductEnum;
import com.xbongbong.saas.enums.product.OutstockProductEnum;
import com.xbongbong.saas.enums.product.ProductionInstockProductEnum;
import com.xbongbong.saas.enums.product.ProductionMaterielOutstockProductEnum;
import com.xbongbong.saas.enums.product.ProductionOrderMaterielProductEnum;
import com.xbongbong.saas.enums.product.PurchaseInstockProductEnum;
import com.xbongbong.saas.enums.product.PurchaseProductEnum;
import com.xbongbong.saas.enums.product.QuotationProductEnum;
import com.xbongbong.saas.enums.product.RefundInstockProductEnum;
import com.xbongbong.saas.enums.product.RefundProductEnum;
import com.xbongbong.saas.enums.product.ReturnPurchaseProductEnum;
import com.xbongbong.saas.enums.product.ReturnedMaterielInstockProductEnum;
import com.xbongbong.saas.enums.product.ReturnedPurchaseOutstockProductEnum;
import com.xbongbong.saas.enums.product.TransferProductEnum;
import com.xbongbong.saas.enums.product.WorkOrderOutstockProductEnum;
import com.xbongbong.saas.enums.product.WorkOrderProductEnum;
import com.xbongbong.saas.help.FundHelp;
import com.xbongbong.saas.help.SaasSaveHelp;
import com.xbongbong.saas.model.ContactModel;
import com.xbongbong.saas.model.ContactUserModel;
import com.xbongbong.saas.model.ContractModel;
import com.xbongbong.saas.model.ContractPerformanceModel;
import com.xbongbong.saas.model.ContractUserModel;
import com.xbongbong.saas.model.CustomerUserModel;
import com.xbongbong.saas.model.DetailTabConfigModel;
import com.xbongbong.saas.model.FundAccountModel;
import com.xbongbong.saas.model.InvoiceModel;
import com.xbongbong.saas.model.InvoiceRelationshipModel;
import com.xbongbong.saas.model.PaymentModel;
import com.xbongbong.saas.model.PaymentSheetModel;
import com.xbongbong.saas.model.PaymentUserModel;
import com.xbongbong.saas.model.PurchaseInvoiceModel;
import com.xbongbong.saas.model.PurchaseInvoiceRelationshipModel;
import com.xbongbong.saas.model.WorkOrderExplainModel;
import com.xbongbong.saas.script.help.InitExplainsHelper;
import com.xbongbong.saas.script.modifyenum.FundContractScriptEnum;
import com.xbongbong.saas.script.modifyenum.FundPayPlanScriptEnum;
import com.xbongbong.saas.script.modifyenum.FundPaymentScriptEnum;
import com.xbongbong.saas.script.modifyenum.FundPurchaseScriptEnum;
import com.xbongbong.saas.script.tempenum.TempAssembleEnum;
import com.xbongbong.saas.script.tempenum.TempBadDebtEnum;
import com.xbongbong.saas.script.tempenum.TempBatchFlowBillEnum;
import com.xbongbong.saas.script.tempenum.TempBomBillEnum;
import com.xbongbong.saas.script.tempenum.TempClueEnum;
import com.xbongbong.saas.script.tempenum.TempCommunicatePlanEnum;
import com.xbongbong.saas.script.tempenum.TempContactEnum;
import com.xbongbong.saas.script.tempenum.TempContractEnum;
import com.xbongbong.saas.script.tempenum.TempContractOutstockEnum;
import com.xbongbong.saas.script.tempenum.TempCustomerCommunicateEnum;
import com.xbongbong.saas.script.tempenum.TempCustomerManagementEnum;
import com.xbongbong.saas.script.tempenum.TempFundTransferEnum;
import com.xbongbong.saas.script.tempenum.TempInstockEnum;
import com.xbongbong.saas.script.tempenum.TempInventoryEnum;
import com.xbongbong.saas.script.tempenum.TempInvoiceEnum;
import com.xbongbong.saas.script.tempenum.TempMarketActivityEnum;
import com.xbongbong.saas.script.tempenum.TempOriStockEnum;
import com.xbongbong.saas.script.tempenum.TempOtherExpenseEnum;
import com.xbongbong.saas.script.tempenum.TempOtherIncomeEnum;
import com.xbongbong.saas.script.tempenum.TempOutstockEnum;
import com.xbongbong.saas.script.tempenum.TempPayPlanEnum;
import com.xbongbong.saas.script.tempenum.TempPaySheetEnum;
import com.xbongbong.saas.script.tempenum.TempPaymentEnum;
import com.xbongbong.saas.script.tempenum.TempPaymentSheetEnum;
import com.xbongbong.saas.script.tempenum.TempPaymentTaskEnum;
import com.xbongbong.saas.script.tempenum.TempPrepayBalanceEnum;
import com.xbongbong.saas.script.tempenum.TempPrepaymentBalanceEnum;
import com.xbongbong.saas.script.tempenum.TempProductEnum;
import com.xbongbong.saas.script.tempenum.TempProductionInstockEnum;
import com.xbongbong.saas.script.tempenum.TempProductionMaterielOutstockEnum;
import com.xbongbong.saas.script.tempenum.TempProductionOrderEnum;
import com.xbongbong.saas.script.tempenum.TempPurchaseEnum;
import com.xbongbong.saas.script.tempenum.TempPurchaseInstockEnum;
import com.xbongbong.saas.script.tempenum.TempPurchaseInvoiceEnum;
import com.xbongbong.saas.script.tempenum.TempPushNotifyEnum;
import com.xbongbong.saas.script.tempenum.TempQuotationEnum;
import com.xbongbong.saas.script.tempenum.TempRedPaymentSheetEnum;
import com.xbongbong.saas.script.tempenum.TempRefundEnum;
import com.xbongbong.saas.script.tempenum.TempRefundInstockEnum;
import com.xbongbong.saas.script.tempenum.TempReturnedMaterielInstockEnum;
import com.xbongbong.saas.script.tempenum.TempReturnedPurchaseEnum;
import com.xbongbong.saas.script.tempenum.TempReturnedPurchaseOutstockEnum;
import com.xbongbong.saas.script.tempenum.TempSalesOpportunityEnum;
import com.xbongbong.saas.script.tempenum.TempStockProductEnum;
import com.xbongbong.saas.script.tempenum.TempSupplierCommunicateEnum;
import com.xbongbong.saas.script.tempenum.TempSupplierContactEnum;
import com.xbongbong.saas.script.tempenum.TempSupplierEnum;
import com.xbongbong.saas.script.tempenum.TempTransferEnum;
import com.xbongbong.saas.script.tempenum.TempWarehouseEnum;
import com.xbongbong.saas.script.tempenum.TempWorkOrderEnum;
import com.xbongbong.saas.script.tempenum.TempWorkOrderOutstockEnum;
import com.xbongbong.saas.script.tempenum.TempWorkReportDailyEnum;
import com.xbongbong.saas.script.tempenum.TempWorkReportMonthlyEnum;
import com.xbongbong.saas.script.tempenum.TempWorkReportWeeklyEnum;
import com.xbongbong.saas.script.tempenum.product.TempContractOutstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempContractProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempInstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempInventoryProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempOriStockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempOutstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempProductionInstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempProductionMaterielOutstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempProductionOrderMaterieProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempPurchaseInstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempPurchaseProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempQuotationProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempRefundInstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempRefundProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempReturnPurchaseProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempReturnedMaterielInstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempReturnedPurchaseOutstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempTransferProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempWorkOrderOutstockProductEnum;
import com.xbongbong.saas.script.tempenum.product.TempWorkOrderProductEnum;
import com.xbongbong.saas.service.ContractService;
import com.xbongbong.saas.service.PaymentService;
import com.xbongbong.saas.service.RepairExplainService;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.CompanyConfigEntity;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.model.CompanyConfigModel;
import com.xbongbong.sys.model.CompanyModel;
import com.xbongbong.sys.model.DepartmentModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getDoubleFromFormData;
import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getDoubleOrDefaultFromFormData;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author haibin.zhang
 * @version v1.0
 * @date 2019/6/19 20:49
 * @since v1.0
 */
@Slf4j
@Service("repairExplainService")
public class RepairExplainServiceImpl extends AbstractPaasRepairExplainService implements RepairExplainService  {
    private static final Logger LOGGER = LoggerFactory.getLogger(RepairExplainServiceImpl.class);
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private WorkOrderExplainModel workOrderExplainModel;
    @Resource
    private PaasFormExplainService paasFormExplainService;
    @Resource
    private PaymentService paymentService;
    @Resource
    private CompanyModel companyModel;
    @Resource
    private EsHelper esHelper;
    @Resource
    private ContractModel contractModel;
    @Resource
    private ContractService contractService;
    @Resource
    private InvoiceRelationshipModel invoiceRelationshipModel;
    @Resource
    private PurchaseInvoiceRelationshipModel purchaseInvoiceRelationshipModel;
    @Resource
    private PaymentModel paymentModel;
    @Resource
    private InvoiceModel invoiceModel;
    @Resource
    private PurchaseInvoiceModel purchaseInvoiceModel;
    @Resource
    private PaasProcessDataModel paasProcessDataModel;
    @Resource
    private PaymentSheetModel paymentSheetModel;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private SaasSaveHelp saasSaveHelp;
    @Resource
    private PaasListGroupModel paasListGroupModel;
    @Resource
    private DetailTabConfigModel detailTabConfigModel;
    @Resource
    private OperateLogService operateLogService;
    @Resource
    private DepartmentModel departmentModel;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private FundAccountModel fundAccountModel;
    @Resource
    private FundHelp fundHelp;
    @Resource
    private SearchCustomerCompanyModel searchCustomerCompanyModel;
    @Resource
    private FineClueCompanyModel fineClueCompanyModel;
    @Resource
    private ContractPerformanceModel contractPerformanceModel;
    @Resource
    private ContractUserModel contractUserModel;
    @Resource
    private PaymentUserModel paymentUserModel;
    @Resource
    private PackageHelp packageHelp;
    @Resource
    private ContactModel contactModel;
    @Resource
    private ContactUserModel contactUserModel;
    @Resource
    private CustomerUserModel customerUserModel;




    @Override
    public ScriptVO addCustomerPid(AllScriptDTO allScriptDTO) throws XbbException {
        ScriptVO scriptVO = new ScriptVO();
        long start = DateTimeUtil.getInt();
        List<String> corpidList = allScriptDTO.getCorpidList();
        // 使用operate区分是否查询旧搜客的工商查询
        RepairExplainEnum repairExplainEnum = RepairExplainEnum.getByCode(allScriptDTO.getOperate());
        if (CollectionsUtil.isEmpty(corpidList)) {
            if (repairExplainEnum == RepairExplainEnum.REPAIR) {
                corpidList = searchCustomerCompanyModel.getCorpidListWithType(SoukeMealEnum.BUSINESS.getType());
            } else {
                corpidList = paasFormExplainModel.getCorpidList();
            }
        }
        // todo 添加corpid=0的公司
//        corpidList.add("0");


        Integer index = 1;
        List<String> errorList = new ArrayList<>();
        List<Integer> businessTypeIn = Arrays.asList(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), XbbRefTypeEnum.CLUE.getCode());
        Map<String, Object> param = new HashMap<>();
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("businessTypeIn", businessTypeIn);
        for (String corpid : corpidList) {
            LOGGER.warn(index + "/" + corpidList.size());
            index++;
            // todo 临时处理方案
            if (repairExplainEnum == RepairExplainEnum.REPAIR) {
                SearchCustomerCompanyEntity soukeCompanyEntity = searchCustomerCompanyModel.getByCorpid(corpid, SoukeMealEnum.BUSINESS.getType());
                if (soukeCompanyEntity == null) {
                    continue;
                }
            }
            param.put(StringConstant.CORPID, corpid);
            List<PaasFormExplainEntity> formExplainEntityList = paasFormExplainModel.findEntitys(param);
            if (CollectionsUtil.isEmpty(formExplainEntityList)) {
                continue;
            }
            List<PaasFormExplainEntity> updateList = new ArrayList<>(formExplainEntityList.size());
            for (PaasFormExplainEntity entity : formExplainEntityList) {
                String explains = entity.getExplains();
                if (StringUtil.isEmpty(entity.getExplains())) {
                    continue;
                }
                List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(explains, FieldAttrEntity.class);
                if (CollectionsUtil.isEmpty(fieldAttrEntityList)) {
                    continue;
                }
                // 字段是否存在
                String needAddAttr1;
                String needAddAttr2;
                if (Objects.equals(XbbRefTypeEnum.CLUE.getCode(), entity.getBusinessType())) {
//                    needAddAttr1 = ClueEnum.EXTERNAL_DATA_ID.getAttr();
//                    needAddAttr2 = ClueEnum.EXTERNAL_DATA_SOURCE.getAttr();
                } else {
//                    needAddAttr1 = CustomerManagementEnum.EXTERNAL_DATA_ID.getAttr();
//                    needAddAttr2 = CustomerManagementEnum.EXTERNAL_DATA_SOURCE.getAttr();
                }
                needAddAttr1 = "";
                needAddAttr2 = "";
                Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(explains, null);
                boolean needAdd1 = !explainMap.containsKey(needAddAttr1);
                boolean needAdd2 = !explainMap.containsKey(needAddAttr2);
                if (needAdd1) {
                    // 数据id
                    FieldAttrEntity externalDataId = InitExplainsHelper.getNewFieldAttrEntity();
                    if (Objects.equals(XbbRefTypeEnum.CLUE.getCode(), entity.getBusinessType())) {
//                        BeanUtil.copyProperties(ClueEnum.EXTERNAL_DATA_ID, externalDataId);
//                        externalDataId.setAttrNameEn(ClueEnum.EXTERNAL_DATA_ID.getAttrName());
//                        externalDataId.setDefaultName(ClueEnum.EXTERNAL_DATA_ID.getAttrName());
                    } else {
//                        BeanUtil.copyProperties(CustomerManagementEnum.EXTERNAL_DATA_ID, externalDataId);
//                        externalDataId.setAttrNameEn(CustomerManagementEnum.EXTERNAL_DATA_ID.getAttrName());
//                        externalDataId.setDefaultName(CustomerManagementEnum.EXTERNAL_DATA_ID.getAttrName());
                    }
                    externalDataId.setAttrType("text");
                    externalDataId.setIsRedundant(0);
                    externalDataId.setEditable(0);
                    fieldAttrEntityList.add(externalDataId);
                }
                if (needAdd2) {
                    // 数据来源
                    FieldAttrEntity externalDataSource = InitExplainsHelper.getNewFieldAttrEntity();
                    if (Objects.equals(XbbRefTypeEnum.CLUE.getCode(), entity.getBusinessType())) {
//                        BeanUtil.copyProperties(ClueEnum.EXTERNAL_DATA_SOURCE, externalDataSource);
//                        externalDataSource.setAttrNameEn(ClueEnum.EXTERNAL_DATA_SOURCE.getAttrName());
//                        externalDataSource.setDefaultName(ClueEnum.EXTERNAL_DATA_SOURCE.getAttrName());
                    } else {
//                        BeanUtil.copyProperties(CustomerManagementEnum.EXTERNAL_DATA_SOURCE, externalDataSource);
//                        externalDataSource.setAttrNameEn(CustomerManagementEnum.EXTERNAL_DATA_SOURCE.getAttrName());
//                        externalDataSource.setDefaultName(CustomerManagementEnum.EXTERNAL_DATA_SOURCE.getAttrName());
                    }
                    externalDataSource.setAttrType("num");
                    externalDataSource.setIsRedundant(0);
                    externalDataSource.setIsOpen(0);
                    externalDataSource.setEditable(0);
                    externalDataSource.setShowEditable(0);
                    fieldAttrEntityList.add(externalDataSource);
                }
                if (needAdd1 || needAdd2) {
                    entity.setExplains(JSONObject.toJSONString(fieldAttrEntityList));
                    updateList.add(entity);
                }
            }
            if (CollectionsUtil.isNotEmpty(updateList)) {
                try {
                    paasFormExplainModel.updateBatch(updateList, corpid);
                } catch (Exception e) {
                   errorList.add(corpid);
                }
            }
        }
        String s = "花费时间：" + ((DateTimeUtil.getInt() - start) / 60) + "分；更新失败formid：" + errorList.toString();
        scriptVO.setMsg(s);
        LOGGER.warn(s);
        return scriptVO;
    }

    @Override
    public ScriptVO delCustomerPid(AllScriptDTO allScriptDTO) throws XbbException {
        ScriptVO scriptVO = new ScriptVO();
        long start = DateTimeUtil.getInt();
        List<String> corpidList = allScriptDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = paasFormExplainModel.getCorpidList();
        }


        Integer index = 1;
        List<String> errorList = new ArrayList<>();
        List<Integer> businessTypeIn = Arrays.asList(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), XbbRefTypeEnum.CLUE.getCode());
        Map<String, Object> param = new HashMap<>();
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("businessTypeIn", businessTypeIn);

        String needDelAttr1;
        String needDelAttr2;

        for (String corpid : corpidList) {
            LOGGER.warn(index + "/" + corpidList.size());
            index++;
            param.put(StringConstant.CORPID, corpid);
            List<PaasFormExplainEntity> formExplainEntityList = paasFormExplainModel.findEntitys(param);
            if (CollectionsUtil.isEmpty(formExplainEntityList)) {
                continue;
            }
            List<PaasFormExplainEntity> updateList = new ArrayList<>(formExplainEntityList.size());
            for (PaasFormExplainEntity entity : formExplainEntityList) {
                String explains = entity.getExplains();
                if (StringUtil.isEmpty(entity.getExplains())) {
                    continue;
                }
                List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(explains, FieldAttrEntity.class);
                if (CollectionsUtil.isEmpty(fieldAttrEntityList)) {
                    continue;
                }
                needDelAttr1 = Objects.equals(XbbRefTypeEnum.CLUE.getCode(), entity.getBusinessType()) ? "text_81" : "text_84";
                needDelAttr2 = Objects.equals(XbbRefTypeEnum.CLUE.getCode(), entity.getBusinessType()) ? "num_64" : "num_65";
                boolean update = false;
                Iterator<FieldAttrEntity> iterator = fieldAttrEntityList.iterator();
                while (iterator.hasNext()){
                    FieldAttrEntity fieldAttrEntity = iterator.next();
                    if (Objects.equals(fieldAttrEntity.getAttr(), needDelAttr1) || Objects.equals(fieldAttrEntity.getAttr(), needDelAttr2)){
                        iterator.remove();
                        update = true;
                    }
                }
                if (update) {
                    entity.setExplains(JSONObject.toJSONString(fieldAttrEntityList));
                    updateList.add(entity);
                }
            }
            if (CollectionsUtil.isNotEmpty(updateList)) {
                try {
                    paasFormExplainModel.updateBatch(updateList, corpid);
                } catch (Exception e) {
                    errorList.add(corpid);
                }
            }
        }
        String s = "花费时间：" + (DateTimeUtil.getInt() - start) + "秒；更新失败corpid：" + errorList.toString();
        scriptVO.setMsg(s);
        LOGGER.warn(s);
        return scriptVO;
    }

    @Override
    public ScriptVO repairExplainProduct(AllScriptDTO allScriptDTO) throws XbbException {
        long start = DateTimeUtil.getInt();
        String corpid = allScriptDTO.getCorpid();
        Integer businessType = allScriptDTO.getBusinessType();
        String fieldAttr = allScriptDTO.getFieldAttr();
        boolean updateFieldAttr = !fieldAttr.isEmpty();
        Class<?> clazz = getBusinessProductClass(businessType);
        Class<?> tempClazz = getBusinessProductTempClass(businessType);
        List<String> fieldAttrList = InitExplainsHelper.getBusinessEnumAttrs(CustomerManagementEnum.class);
        if (updateFieldAttr && (!fieldAttrList.contains(fieldAttr) || Objects.equals(fieldAttr,"attr"))){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001,"非法的字段属性");
        }
        RepairExplainEnum repairExplainEnum = RepairExplainEnum.getByCode(allScriptDTO.getOperate());
        List<String> corpidList = allScriptDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = companyModel.getCorpidList();
        }
        allScriptDTO.setCorpidList(corpidList);

        switch (repairExplainEnum){
            case REPAIR:
                repairSaasExplainProduct(allScriptDTO, clazz, tempClazz);
                break;
            case DEL:
                delSaasExplain(allScriptDTO, clazz, tempClazz);
                break;
            case ADD:
                addSaasExplainProduct(allScriptDTO, clazz, tempClazz);
                break;
            default:
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001,"未知操作");


        }
        LOGGER.warn("consume:" + (DateTimeUtil.getInt() - start));
        return null;
    }

        private void addSaasExplainProduct(AllScriptDTO allScriptDTO, Class<?> clazz, Class<?> tempClazz) throws XbbException{
            String attr = allScriptDTO.getAttr();
            String afterAttr = allScriptDTO.getAfterAttr();
            Integer businessType = allScriptDTO.getBusinessType();
            boolean insertFieldAttr = !attr.isEmpty();
            LOGGER.warn(allScriptDTO.getCorpidList().size() + "家公司");
            Integer index = 1;
            List<Long> failList = new ArrayList<>();
            for (String corpid : allScriptDTO.getCorpidList()) {
                LOGGER.warn(index + "/" + allScriptDTO.getCorpidList().size());
                index++;
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", corpid);
                param.put("del", 0);
                param.put("businessType", businessType);
                if (allScriptDTO.getFormId() != null) {
                    param.put("formId", allScriptDTO.getFormId());
                }
                List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.list(param);
                Map<String, Object> enumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                Object[] objs = clazz.getEnumConstants();
                for (Object obj : objs) {
                    try {
                        String name = (String) clazz.getMethod("getAttr").invoke(obj);
                        enumMap.put(name, obj);
                    } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                        e.printStackTrace();
                    }
                }
                //思路: 将写好的枚举 分别装入 fieldAttrEntity
                for(PaasFormExplainEntity entity : paasFormExplainEntityList) {
                    boolean canInsert = true;
                    List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(entity.getExplains(),FieldAttrEntity.class);
                    for(int i = 0; i < fieldAttrEntityList.size(); i++){
                        //插入到当前字段后面
                        FieldAttrEntity fieldAttrEntity = fieldAttrEntityList.get(i);
                        if (Objects.equals(FieldTypeEnum.SELECT_PRODUCT.getType(), fieldAttrEntity.getFieldType())) {
                            if (Objects.equals(businessType, XbbRefTypeEnum.PRODUCTION_ORDER.getCode()) && Objects.equals(fieldAttrEntity.getAttr(),ProductionOrderEnum.PRODUCT.getAttr())) {
                                continue;
                            }
                            if (Objects.isNull(fieldAttrEntity.getSubForm()) || Objects.isNull(fieldAttrEntity.getSubForm().getItems())) {
                                LOGGER.warn("关联产品没有subForm的corpid:" + entity.getCorpid() + "/解释id:" + entity.getId() + "/formId:" + entity.getFormId());
                                continue;
                            }
                            List<FieldAttrEntity> subExplainList = (List<FieldAttrEntity>) fieldAttrEntity.getSubForm().getItems();
                            for (int k = 0;k < subExplainList.size(); k++) {
                                FieldAttrEntity attrEntity1 = subExplainList.get(k);
                                if (Objects.equals(attrEntity1.getAttr(), attr)) {
                                    LOGGER.error(corpid + "该公司已存在" + attr + "字段");
                                    canInsert = false;
                                    break;
                                }
                            }
                            if (canInsert) {
                                for (int j = 0;j < subExplainList.size(); j++) {
                                    FieldAttrEntity attrEntity = subExplainList.get(j);
                                    if(Objects.equals(afterAttr,attrEntity.getAttr())) {
                                        if (insertFieldAttr) {
                                            try {
                                                // 包装业务枚举类;
                                                List<String> enumAttrs = null;
                                                if (enumAttrs == null) {
                                                    // 获取业务枚举类中的属性，以集合的形式返回，同一个枚举的属性值只获取一次
                                                    enumAttrs = InitExplainsHelper.getBusinessEnumAttrs(clazz);
                                                }
                                                Object obj = enumMap.get(attr);
                                                // 初始化字段解释
                                                FieldAttrEntity newFieldAttrEntity = InitExplainsHelper.setField(clazz, enumAttrs,obj);
                                                if (newFieldAttrEntity != null) {
                                                    String saasAttr = newFieldAttrEntity.getSaasAttr();
                                                    String initAttr = saasAttr.substring(0, 1).toUpperCase() + saasAttr.substring(1);
                                                    String methodName = "init" + initAttr;
                                                    try {
                                                        //这里拿到了新加入字段的初始化方法 并执行它 参数为 他的实例
                                                        Method methodHasParameter = tempClazz.getMethod(methodName, FieldAttrEntity.class);
                                                        methodHasParameter.invoke(tempClazz, newFieldAttrEntity);
                                                    } catch (NoSuchMethodException e) {
                                                        // 没有对应字段的初始化方法
                                                    } catch (Exception e) {
                                                        LOGGER.warn(e.getMessage());
                                                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
                                                    }
                                                    newFieldAttrEntity.setParentAttr(fieldAttrEntity.getAttr());
                                                    newFieldAttrEntity.setIsForbidden(0);
                                                    subExplainList.add(j + 1,newFieldAttrEntity);
                                                    fieldAttrEntity.getSubForm().setItems(subExplainList);
                                                    entity.setExplains(JSONObject.toJSONString(fieldAttrEntityList));

                                                }
                                            } catch (Exception e) {
                                                failList.add(entity.getId());
                                                e.printStackTrace();
                                            }
                                        }
                                    }
                                }
                            }
                            break;
                        }
                    }
                    if (canInsert) {
                        paasFormExplainModel.update(entity);
                    }
                }
            }
            if (failList.isEmpty()) {
                throw new XbbException(ErrorCodeEnum.API_SUCCESS, "更新成功");
            } else {
                throw new XbbException(ErrorCodeEnum.API_SUCCESS, "部分更新成功，id " + failList + "更新失败");
            }

        }



    @Override
    public ScriptVO changeExplainOrder(AllScriptDTO allScriptDTO) throws XbbException{
        Integer businessType = allScriptDTO.getBusinessType();
        List<String> corpidList = allScriptDTO.getCorpidList();
        if (corpidList.isEmpty()){
            corpidList = paasFormExplainModel.getCorpidList();
            corpidList.remove("0");
        }
        LOGGER.warn(corpidList.size() + "家公司");
        Integer index = 1;
        List<Long> failList = new ArrayList<>();
        for (String corpid : corpidList) {
            LOGGER.warn(index + "/" + corpidList.size());
            index++;
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("del", 0);
            param.put("businessType", businessType);
            if (allScriptDTO.getFormId() != null) {
                param.put("formId", allScriptDTO.getFormId());
            }
            List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.list(param);
            if (paasFormExplainEntityList.isEmpty()) {
                continue;
            }
            for(PaasFormExplainEntity entity : paasFormExplainEntityList) {
                List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(entity.getExplains(),FieldAttrEntity.class);
                Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(entity.getExplains(), null);
                if (explainMap.containsKey(CustomerManagementEnum.CONTACT_NAME.getAttr()) && explainMap.containsKey(CustomerManagementEnum.CONTACT_PHONE.getAttr())) {
                    List<FieldAttrEntity> newList = new ArrayList<>(fieldAttrEntityList.size());
                    FieldAttrEntity contactNameField = null;
                    FieldAttrEntity contactPhoneField = null;
                    for (FieldAttrEntity fieldAttrEntity : fieldAttrEntityList) {
                        if (Objects.equals(fieldAttrEntity.getAttr(), CustomerManagementEnum.CONTACT_NAME.getAttr())) {
                            contactNameField = fieldAttrEntity;
                        } else if (Objects.equals(fieldAttrEntity.getAttr(), CustomerManagementEnum.CONTACT_PHONE.getAttr())) {
                            contactPhoneField = fieldAttrEntity;
                        } else {
                            newList.add(fieldAttrEntity);
                        }
                    }
                    newList.add(0, contactNameField);
                    newList.add(1, contactPhoneField);
                    entity.setExplains(JSONObject.toJSONString(newList));
                    paasFormExplainModel.update(entity);
                } else {
                    failList.add(entity.getId());
                }
            }
        }
        if (failList.isEmpty()) {
            throw new XbbException(ErrorCodeEnum.API_SUCCESS, "更新成功");
        } else {
            throw new XbbException(ErrorCodeEnum.API_SUCCESS, "部分更新成功，id " + failList + "更新失败");
        }
    }




    /**
     * saas关联产品的字段解释修复
     * @param allScriptDTO 入参
     * @param clazz 主枚举
     * @param tempClazz 辅助枚举
     * @throws XbbException
     */
    private void repairSaasExplainProduct(AllScriptDTO allScriptDTO, Class<?> clazz, Class<?> tempClazz) throws XbbException {
        String attr = allScriptDTO.getAttr();
        String fieldAttr = allScriptDTO.getFieldAttr();
        boolean updateFieldAttr = !fieldAttr.isEmpty();
        Integer businessType = allScriptDTO.getBusinessType();
        LOGGER.warn(allScriptDTO.getCorpidList().size() + "家公司");
        Integer index = 1;
        List<Long> failList = new ArrayList<>();
        for (String corpid : allScriptDTO.getCorpidList()) {
            LOGGER.warn(index + "/" + allScriptDTO.getCorpidList().size());
            index++;
            List<WorkOrderExplainEntity> updateList = new ArrayList<>();
            if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", corpid);
                param.put("del", 0);
                param.put("businessType", businessType);
                List<WorkOrderExplainEntity> workOrderExplainEntityExtList = workOrderExplainModel.findEntitys(param);
                for (WorkOrderExplainEntity entity : workOrderExplainEntityExtList) {
                    boolean update = false;
                    List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(entity.getExplains(), FieldAttrEntity.class);
                    String fieldAttrInvoke = fieldAttr.substring(0, 1).toUpperCase() + fieldAttr.substring(1);
                    for (FieldAttrEntity fieldAttrEntity : fieldAttrEntityList) {
                        if (Objects.equals(FieldTypeEnum.SELECT_PRODUCT.getType(), fieldAttrEntity.getFieldType())) {
                            if (Objects.isNull(fieldAttrEntity.getSubForm()) || Objects.isNull(fieldAttrEntity.getSubForm().getItems())){
                                LOGGER.warn("实施备件没有subForm的corpid:" + entity.getCorpid() + "/解释id:" + entity.getId() + "/formId:" + entity.getFormId());
                                continue;
                            }
                            List<FieldAttrEntity> subExplainList = (List<FieldAttrEntity>) fieldAttrEntity.getSubForm().getItems();
                            for (FieldAttrEntity subEntity : subExplainList) {
                                if (updateFieldAttr) {
                                    if (Objects.equals(attr, subEntity.getAttr())) {
                                        try {
                                            Object value = allScriptDTO.getInitMethodFieldValue();
                                            Class<?> returnType = clazz.getMethod("get" + fieldAttrInvoke).getReturnType();
                                            Method method = FieldAttrEntity.class.getMethod("set" + fieldAttrInvoke, returnType);
                                            method.invoke(subEntity, value);
                                            fieldAttrEntity.getSubForm().setItems(subExplainList);
                                        }catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                                            e.printStackTrace();
                                        }
                                        update = true;
                                    }
                                }
                            }
                            continue;
                        }
                    }
                    if (update) {
                        entity.setExplains(JSONArray.toJSONString(fieldAttrEntityList));
                        updateList.add(entity);
                    } else {
                        failList.add(entity.getId());
                    }
                }
            }
            if (updateList.isEmpty()) {
//                throw new XbbException(ErrorCodeEnum.API_SUCCESS, "未找到更新内容");
            } else {
                for (WorkOrderExplainEntity entity : updateList) {
                    workOrderExplainModel.update(entity);
                }
            }
        }
        if (failList.isEmpty()) {
            throw new XbbException(ErrorCodeEnum.API_SUCCESS, "更新成功");
        } else {
            throw new XbbException(ErrorCodeEnum.API_SUCCESS, "部分更新成功，id " + failList + "更新失败");
        }
    }

    /**
     * 获取主枚举关联产品
     * @param businessType 业务类型
     * @return 枚举
     * @throws XbbException
     */
    @Override
    public Class<?> getBusinessProductTempClass(Integer businessType) throws XbbException {
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        switch (xbbRefTypeEnum){
            case CONTRACT:
                return TempContractProductEnum.class;
            case PURCHASE:
                return TempPurchaseProductEnum.class;
            case RETURNED_PURCHASE:
                return TempReturnPurchaseProductEnum.class;
            case PURCHASE_INSTOCK:
                return TempPurchaseInstockProductEnum.class;
            case OTHER_INSTOCK:
                return TempInstockProductEnum.class;
            case REFUND_INSTOCK:
                return TempRefundInstockProductEnum.class;
            case PRODUCTION_INSTOCK:
                return TempProductionInstockProductEnum.class;
            case RETURNED_MATERIEL_INSTOCK:
                return TempReturnedMaterielInstockProductEnum.class;
            case CONTRACT_OUTSTOCK:
                return TempContractOutstockProductEnum.class;
            case OTHER_OUTSTOCK:
                return TempOutstockProductEnum.class;
            case RETURNED_PURCHASE_OUTSTOCK:
                return TempReturnedPurchaseOutstockProductEnum.class;
            case PRODUCTION_MATERIEL_OUTSTOCK:
                return TempProductionMaterielOutstockProductEnum.class;
            case WORK_ORDER_OUTSTOCK:
                return TempWorkOrderOutstockProductEnum.class;
            case INVENTORY:
                return TempInventoryProductEnum.class;
            case TRANSFER:
                return TempTransferProductEnum.class;
            case PRODUCTION_ORDER:
                return TempProductionOrderMaterieProductEnum.class;
            case WORK_ORDER:
                return TempWorkOrderProductEnum.class;
            case REFUND:
                return TempRefundProductEnum.class;
            case QUOTATION:
                return TempQuotationProductEnum.class;
            case ORI_STOCK:
                return TempOriStockProductEnum.class;
            default:
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001,"非法的业务类型");
        }
    }

    /**
     * 获取主枚举
     * @param businessType 业务类型
     * @return 枚举
     * @throws XbbException
     */
    @Override
    public Class<?> getBusinessTempClass(Integer businessType) throws XbbException {
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        switch (xbbRefTypeEnum){
            case CUSTOMER_MANAGEMENT:
                return TempCustomerManagementEnum.class;
            case CONTRACT:
                return TempContractEnum.class;
            case SALES_OPPORTUNITY:
                return TempSalesOpportunityEnum.class;
            case CONTACT:
                return TempContactEnum.class;
            case CUSTOMER_COMMUNICATE:
                return TempCustomerCommunicateEnum.class;
            case SUPPLIER_COMMUNICATE:
                return TempSupplierCommunicateEnum.class;
            case COMMUNICATE_PLAN:
                return TempCommunicatePlanEnum.class;
            case WORKREPORT_DAILY:
                return TempWorkReportDailyEnum.class;
            case WORKREPORT_WEEKLY:
                return TempWorkReportWeeklyEnum.class;
            case WORKREPORT_MONTHLY:
                return TempWorkReportMonthlyEnum.class;
            case PAYMENT:
                return TempPaymentEnum.class;
            case PAY_PLAN:
                return TempPayPlanEnum.class;
            case INVOICE:
                return TempInvoiceEnum.class;
            case PURCHASE_INVOICE:
                return TempPurchaseInvoiceEnum.class;
            case SUPPLIER:
                return TempSupplierEnum.class;
            case PURCHASE:
                return TempPurchaseEnum.class;
            case RETURNED_PURCHASE:
                return TempReturnedPurchaseEnum.class;
            case SUPPLIER_CONTACT:
                return TempSupplierContactEnum.class;
            case ASSEMBLE:
                return TempAssembleEnum.class;
            case INSTOCK:
                return TempInstockEnum.class;
            case PURCHASE_INSTOCK:
                return TempPurchaseInstockEnum.class;
            case OTHER_INSTOCK:
                return TempInstockEnum.class;
            case REFUND_INSTOCK:
                return TempRefundInstockEnum.class;
            case PRODUCTION_INSTOCK:
                return TempProductionInstockEnum.class;
            case RETURNED_MATERIEL_INSTOCK:
                return TempReturnedMaterielInstockEnum.class;
            case OUTSTOCK:
                return TempOutstockEnum.class;
            case CONTRACT_OUTSTOCK:
                return TempContractOutstockEnum.class;
            case OTHER_OUTSTOCK:
                return TempOutstockEnum.class;
            case RETURNED_PURCHASE_OUTSTOCK:
                return TempReturnedPurchaseOutstockEnum.class;
            case PRODUCTION_MATERIEL_OUTSTOCK:
                return TempProductionMaterielOutstockEnum.class;
            case WORK_ORDER_OUTSTOCK:
                return TempWorkOrderOutstockEnum.class;
            case INVENTORY:
                return TempInventoryEnum.class;
            case TRANSFER:
                return TempTransferEnum.class;
            case BOM_BILL:
                return TempBomBillEnum.class;
            case PRODUCTION_ORDER:
                return TempProductionOrderEnum.class;
            case PRODUCT:
                return TempProductEnum.class;
            case WAREHOUSE:
                return TempWarehouseEnum.class;
            case PAYMENT_SHEET:
                return TempPaymentSheetEnum.class;
            case PAY_SHEET:
                return TempPaySheetEnum.class;
            case WORK_ORDER:
                return TempWorkOrderEnum.class;
            case STOCK_PRODUCT:
                return TempStockProductEnum.class;
            case BAD_DEBT:
                return TempBadDebtEnum.class;
            case RED_PAYMENT_SHEET:
                return TempRedPaymentSheetEnum.class;
            case PUSH_NOTIFY:
                return TempPushNotifyEnum.class;
            case REFUND:
                return TempRefundEnum.class;
            case QUOTATION:
                return TempQuotationEnum.class;
            case ORI_STOCK:
                return TempOriStockEnum.class;
            case PREPAYMENT_BALANCE:
                return TempPrepaymentBalanceEnum.class;
            case PREPAY_BALANCE:
                return TempPrepayBalanceEnum.class;
            case PAYMENT_TASK:
                return TempPaymentTaskEnum.class;
            case BATCH_FLOW_BILL:
                return TempBatchFlowBillEnum.class;
            case CLUE:
                return TempClueEnum.class;
            case MARKET_ACTIVITY:
                return TempMarketActivityEnum.class;
            case OTHER_INCOME:
                return TempOtherIncomeEnum.class;
            case OTHER_EXPENSE:
                return TempOtherExpenseEnum.class;
            case FUND_TRANSFER:
                return TempFundTransferEnum.class;
            default:
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001,"非法的业务类型");
        }
    }

    /**
     * 获取辅助枚举
     * @param businessType 业务类型
     * @return 枚举
     * @throws XbbException
     */
    public Class<?> getBusinessClass(Integer businessType) throws XbbException {
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        switch (xbbRefTypeEnum){
            case CUSTOMER_MANAGEMENT:
                return CustomerManagementEnum.class;
            case CONTRACT:
                return ContractEnum.class;
            case SALES_OPPORTUNITY:
                return SalesOpportunityEnum.class;
            case CONTACT:
                return ContactEnum.class;
            case CUSTOMER_COMMUNICATE:
                return CustomerCommunicateEnum.class;
            case SUPPLIER_COMMUNICATE:
                return SupplierCommunicateEnum.class;
            case COMMUNICATE_PLAN:
                return CommunicatePlanEnum.class;
            case WORKREPORT_DAILY:
                return WorkReportDailyEnum.class;
            case WORKREPORT_WEEKLY:
                return WorkReportWeeklyEnum.class;
            case WORKREPORT_MONTHLY:
                return WorkReportMonthlyEnum.class;
            case PAYMENT:
                return PaymentEnum.class;
            case PAY_PLAN:
                return PayPlanEnum.class;
            case INVOICE:
                return InvoiceEnum.class;
            case SUPPLIER:
                return SupplierEnum.class;
            case PURCHASE:
                return PurchaseEnum.class;
            case RETURNED_PURCHASE:
                return ReturnedPurchaseEnum.class;
            case SUPPLIER_CONTACT:
                return SupplierContactEnum.class;
            case ASSEMBLE:
                return AssembleEnum.class;
            case INSTOCK:
                return InstockEnum.class;
            case PURCHASE_INSTOCK:
                return PurchaseInstockEnum.class;
            case OTHER_INSTOCK:
                return InstockEnum.class;
            case REFUND_INSTOCK:
                return RefundInstockEnum.class;
            case PRODUCTION_INSTOCK:
                return ProductionInstockEnum.class;
            case RETURNED_MATERIEL_INSTOCK:
                return ReturnedMaterielInstockEnum.class;
            case OUTSTOCK:
                return OutstockEnum.class;
            case CONTRACT_OUTSTOCK:
                return ContractOutstockEnum.class;
            case OTHER_OUTSTOCK:
                return OutstockEnum.class;
            case RETURNED_PURCHASE_OUTSTOCK:
                return ReturnedPurchaseOutstockEnum.class;
            case PRODUCTION_MATERIEL_OUTSTOCK:
                return ProductionMaterielOutstockEnum.class;
            case WORK_ORDER_OUTSTOCK:
                return WorkOrderOutstockEnum.class;
            case INVENTORY:
                return InventoryEnum.class;
            case TRANSFER:
                return TransferEnum.class;
            case BOM_BILL:
                return BomBillEnum.class;
            case PRODUCTION_ORDER:
                return ProductionOrderEnum.class;
            case PRODUCT:
                return ProductEnum.class;
            case WAREHOUSE:
                return WarehouseEnum.class;
            case PAYMENT_SHEET:
                return PaymentSheetEnum.class;
            case PAY_SHEET:
                return PaySheetEnum.class;
            case WORK_ORDER:
                return WorkOrderEnum.class;
            case STOCK_PRODUCT:
                return StockProductEnum.class;
            case BAD_DEBT:
                return BadDebtEnum.class;
            case RED_PAYMENT_SHEET:
                return RedPaymentSheetEnum.class;
            case PUSH_NOTIFY:
                return PushNotifyEnum.class;
            case REFUND:
                return RefundEnum.class;
            case QUOTATION:
                return QuotationEnum.class;
            case ORI_STOCK:
                return OriStockEnum.class;
            case BATCH_FLOW_BILL:
                return BatchFlowBillEnum.class;
            case CLUE:
                return ClueEnum.class;
            case MARKET_ACTIVITY:
                return MarketActivityEnum.class;
            case PAYMENT_TASK:
                return PaymentTaskEnum.class;
            case OTHER_INCOME:
                return OtherIncomeEnum.class;
            case OTHER_EXPENSE:
                return OtherExpenseEnum.class;
            case FUND_TRANSFER:
                return FundTransferEnum.class;
            default:
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001,"非法的业务类型");
        }
    }

    /**
     * 获取辅助枚举
     * @param businessType 业务类型
     * @return 枚举
     * @throws XbbException
     */
    private Class<?> getBusinessProductClass(Integer businessType) throws XbbException {
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        switch (xbbRefTypeEnum){
            case CUSTOMER_MANAGEMENT:
                return CustomerManagementEnum.class;
            case CONTRACT:
                return ContractProductEnum.class;
            case PURCHASE:
                return PurchaseProductEnum.class;
            case RETURNED_PURCHASE:
                return ReturnPurchaseProductEnum.class;
            case PURCHASE_INSTOCK:
                return PurchaseInstockProductEnum.class;
            case OTHER_INSTOCK:
                return InstockProductEnum.class;
            case REFUND_INSTOCK:
                return RefundInstockProductEnum.class;
            case PRODUCTION_INSTOCK:
                return ProductionInstockProductEnum.class;
            case RETURNED_MATERIEL_INSTOCK:
                return ReturnedMaterielInstockProductEnum.class;
            case CONTRACT_OUTSTOCK:
                return ContractOutstockProductEnum.class;
            case OTHER_OUTSTOCK:
                return OutstockProductEnum.class;
            case RETURNED_PURCHASE_OUTSTOCK:
                return ReturnedPurchaseOutstockProductEnum.class;
            case PRODUCTION_MATERIEL_OUTSTOCK:
                return ProductionMaterielOutstockProductEnum.class;
            case WORK_ORDER_OUTSTOCK:
                return WorkOrderOutstockProductEnum.class;
            case INVENTORY:
                return InventoryProductEnum.class;
            case TRANSFER:
                return TransferProductEnum.class;
            case PRODUCTION_ORDER:
                return ProductionOrderMaterielProductEnum.class;
            case WORK_ORDER:
                return WorkOrderProductEnum.class;
            case REFUND:
                return RefundProductEnum.class;
            default:
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001,"非法的业务类型");
        }
    }

    @Override
    public ScriptVO fixForm(FixFormDTO fixFormDTO) throws XbbException {
        List<String> corpidList = fixFormDTO.getCorpidList();
        if (Objects.isNull(corpidList) || (Objects.nonNull(corpidList) && corpidList.isEmpty())) {
            corpidList = paasFormExplainModel.getCorpidList();
        }
        LOGGER.info("Mantis Shrimp!Let we go");
        Integer total = corpidList.size();
        LOGGER.info("共计公司：" + total);
        Integer index = 1;
//        List<String> corpidList = Collections.singletonList("1");
        for (String corpid : corpidList){
            LOGGER.info("共计公司：" + index + "/" + total);
            index ++;
            for (Integer businessType : fixFormDTO.getBusinessTypeList()) {
                Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid",corpid);
                param.put("businessType",businessType);
                List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.findEntitys(param);
                if (paasFormExplainEntityList.isEmpty()){
                    continue;
                }
                Class<?> clazz = getBusinessClass(businessType);
                Class<?> tempClazz = getBusinessTempClass(businessType);
                List<FieldAttrEntity> fieldAttrEntityList = new ArrayList<>();
                List<String> fieldAttrList = InitExplainsHelper.getBusinessEnumAttrs(clazz);
                fieldAttrList.remove("disableEditAttr");
                Object[] objs = clazz.getEnumConstants();
                for (Object obj : objs) {
                    FieldAttrEntity fieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                    String saasAttr = "";
                    try {
                        for (String fieldAttr : fieldAttrList) {
                            String attr = fieldAttr.substring(0, 1).toUpperCase() + fieldAttr.substring(1);
                            Object value = clazz.getMethod("get" + attr).invoke(obj);
                            Class<?> returnType = clazz.getMethod("get" + attr).getReturnType();
                            Method method = FieldAttrEntity.class.getMethod("set" + attr, returnType);
                            method.invoke(fieldAttrEntity, value);
                            if (Objects.equals(fieldAttr, "saasAttr")) {
                                saasAttr = value.toString();
                            }
                            if (Objects.equals("fieldType",fieldAttr)) {
                                Integer fieldType = Integer.parseInt(value.toString());
                                String esAlias = FieldTypeEnum.getFieldTypeEnum(fieldType).getEsalias();
                                fieldAttrEntity.setAttrType(esAlias);
                            }
                            if (Objects.equals("attrName",fieldAttr)){
                                fieldAttrEntity.setDefaultName(value.toString());
                            }
                        }
                        //saas 数组越界判断
                        if (saasAttr != null && saasAttr.length() > 0) {
                            Method method = tempClazz.getMethod("init" + saasAttr.substring(0, 1).toUpperCase() + saasAttr.substring(1), FieldAttrEntity.class);
                            InitExplainsHelper.commonFiledInit(fieldAttrEntity);
                            method.invoke(tempClazz, fieldAttrEntity);
                        }
                    } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                        e.printStackTrace();
                    }
                    fieldAttrEntityList.add(fieldAttrEntity);
                }
                for (PaasFormExplainEntity explainEntityExt : paasFormExplainEntityList){
                    explainEntityExt.setExplains(JSONArray.toJSONString(fieldAttrEntityList));
                    paasFormExplainModel.update(explainEntityExt);
                }
            }
        }

        return null;
    }


    @Override
    public FieldAttrEntity addNewField(Integer businessType, String attr) throws XbbException{
        Class<?> clazz = getBusinessClass(businessType);
        Class<?> tempClazz = getBusinessTempClass(businessType);
        Map<String, Object> enumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Object[] objs = clazz.getEnumConstants();
        for (Object obj : objs) {
            try {
                String name = (String) clazz.getMethod("getAttr").invoke(obj);
                enumMap.put(name, obj);
            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
        FieldAttrEntity newFieldAttrEntity = null;
        try {
            // 包装业务枚举类;
            List<String> enumAttrs = null;
            if (enumAttrs == null) {
                // 获取业务枚举类中的属性，以集合的形式返回，同一个枚举的属性值只获取一次
                enumAttrs = InitExplainsHelper.getBusinessEnumAttrs(clazz);
            }
            Object obj = enumMap.get(attr);
            // 初始化字段解释
            newFieldAttrEntity = InitExplainsHelper.setField(clazz, enumAttrs, obj);
            if (newFieldAttrEntity != null) {
                String saasAttr = newFieldAttrEntity.getSaasAttr();
                String initAttr = saasAttr.substring(0, 1).toUpperCase() + saasAttr.substring(1);
                String methodName = "init" + initAttr;
                try {
                    //这里拿到了新加入字段的初始化方法 并执行它 参数为 他的实例
                    Method methodHasParameter = tempClazz.getMethod(methodName, FieldAttrEntity.class);
                    methodHasParameter.invoke(tempClazz, newFieldAttrEntity);
                } catch (NoSuchMethodException e) {
                    // 没有对应字段的初始化方法
                } catch (Exception e) {
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return newFieldAttrEntity;
    }

    @Override
    public ScriptVO fixShowAttrPermission(FixDataJobDTO fixDataJobDTO) throws XbbException {
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (Objects.isNull(corpidList) || (Objects.nonNull(corpidList) && corpidList.isEmpty())) {
            corpidList = paasFormExplainModel.getCorpidList();
        }
        Integer total = corpidList.size();
        LOGGER.info("共计公司：" + total);
        Integer index = 1;

        for (String corpid : corpidList){
            LOGGER.info("共计公司：" + index + "/" + total);
            index ++;
            for (Integer businessType : fixDataJobDTO.getBusinessTypeList()) {
                Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid",corpid);
                param.put("businessType",businessType);
                List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.findEntitys(param);
                if (paasFormExplainEntityList.isEmpty()){
                    continue;
                }
                for (PaasFormExplainEntity explainEntityExt : paasFormExplainEntityList){
                    List<FieldAttrEntity> fieldAttrEntities = JSONArray.parseArray(explainEntityExt.getExplains(), FieldAttrEntity.class);
                    for (FieldAttrEntity fieldAttrEntity : fieldAttrEntities) {
                        if (Objects.equals(fieldAttrEntity.getShowAttrPermission(), 0)) {
                            fieldAttrEntity.setShowAttrPermission(null);
                        }
                    }
                    explainEntityExt.setExplains(JSONArray.toJSONString(fieldAttrEntities));
                    paasFormExplainModel.update(explainEntityExt);
                }
            }
        }
        return new ScriptVO();
    }

    @Override
    public ScriptVO fixContractProductSellPriceFormula(FixDataJobDTO fixDataJobDTO) throws XbbException {
        String formula = "DIVIDE(MULTIPLY({self." + ContractEnum.PRODUCT.getAttr() + "." + SelectProductEnum.PRICE.getAttr() + "},{self." + ContractEnum.PRODUCT.getAttr() + "." + SelectProductEnum.DISCOUNT.getAttr() + "}),100,6)";
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (Objects.isNull(corpidList) || (Objects.nonNull(corpidList) && corpidList.isEmpty())) {
            corpidList = paasFormExplainModel.getCorpidList();
        }
        Integer total = corpidList.size();
        LOGGER.info("共计公司：" + total);
        Integer index = 1;

        for (String corpid : corpidList){
            LOGGER.info("共计公司：" + index + "/" + total);
            index ++;

            Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("del", 0);
            param.put("businessType", XbbRefTypeEnum.CONTRACT.getCode());
            List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.findEntitys(param);
            if (paasFormExplainEntityList.isEmpty()){
                continue;
            }
            for (PaasFormExplainEntity explainEntityExt : paasFormExplainEntityList){
                List<FieldAttrEntity> fieldAttrEntities = JSONArray.parseArray(explainEntityExt.getExplains(), FieldAttrEntity.class);
                for (FieldAttrEntity fieldAttrEntity : fieldAttrEntities) {
                    if (Objects.equals(fieldAttrEntity.getAttr(), ContractEnum.PRODUCT.getAttr())) {
                        List<FieldAttrEntity> subFormExplainList = (List<FieldAttrEntity>) fieldAttrEntity.getSubForm().getItems();
                        for (FieldAttrEntity subFieldAttrEntity : subFormExplainList) {
                            if (Objects.equals(subFieldAttrEntity.getAttr(), ContractProductEnum.SELLING_PRICE.getAttr())) {
                                FormulaPoJo formulaInfo = subFieldAttrEntity.getDefaultAttr().getFormulaInfo();
                                formulaInfo.setFormula(formula);
                            }
                        }
                        fieldAttrEntity.getSubForm().setItems(subFormExplainList);
                    }
                }
                explainEntityExt.setExplains(JSONArray.toJSONString(fieldAttrEntities));
                paasFormExplainModel.update(explainEntityExt);
            }
        }
        return new ScriptVO();
    }

    @Override
    public ScriptVO fixQuotationProductSellPriceFormula(FixDataJobDTO fixDataJobDTO) throws XbbException {
        String productAttr = QuotationEnum.PRODUCT.getAttr();
        String sellPriceAttr = QuotationProductEnum.SELLING_PRICE.getAttr();
        Integer businessType = fixDataJobDTO.getBusinessType();
        if (Objects.equals(businessType, XbbRefTypeEnum.SALES_OPPORTUNITY.getCode())) {
            productAttr = SalesOpportunityEnum.PRODUCTS.getAttr();
            sellPriceAttr = OpportunityProductEnum.SELLING_PRICE.getAttr();
        }
        String formula = "DIVIDE(MULTIPLY({self." + productAttr + "." + SelectProductEnum.PRICE.getAttr() + "},{self." + productAttr + "." + SelectProductEnum.DISCOUNT.getAttr() + "}),100,6)";
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (Objects.isNull(corpidList) || (Objects.nonNull(corpidList) && corpidList.isEmpty())) {
            corpidList = paasFormExplainModel.getCorpidList();
        }
        Integer total = corpidList.size();
        LOGGER.info("共计公司：" + total);
        Integer index = 1;

        for (String corpid : corpidList){
            LOGGER.info("共计公司：" + index + "/" + total);
            index ++;

            Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("del", 0);
            param.put("businessType", businessType);
            List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.findEntitys(param);
            if (paasFormExplainEntityList.isEmpty()){
                continue;
            }
            for (PaasFormExplainEntity explainEntityExt : paasFormExplainEntityList){
                List<FieldAttrEntity> fieldAttrEntities = JSONArray.parseArray(explainEntityExt.getExplains(), FieldAttrEntity.class);
                for (FieldAttrEntity fieldAttrEntity : fieldAttrEntities) {
                    if (Objects.equals(fieldAttrEntity.getAttr(), productAttr)) {
                        List<FieldAttrEntity> subFormExplainList = (List<FieldAttrEntity>) fieldAttrEntity.getSubForm().getItems();
                        for (FieldAttrEntity subFieldAttrEntity : subFormExplainList) {
                            if (Objects.equals(subFieldAttrEntity.getAttr(), sellPriceAttr)) {
                                FormulaPoJo formulaInfo = subFieldAttrEntity.getDefaultAttr().getFormulaInfo();
                                formulaInfo.setFormula(formula);
                            }
                        }
                        fieldAttrEntity.getSubForm().setItems(subFormExplainList);
                    }
                }
                explainEntityExt.setExplains(JSONArray.toJSONString(fieldAttrEntities));
                paasFormExplainModel.update(explainEntityExt);
            }
        }
        return new ScriptVO();
    }

    @Override
    public ScriptVO repairOneBusinessExplain(AllScriptDTO allScriptDTO, List<AllScriptDTO> allScriptDTOList) throws XbbException {
        Integer businessType = allScriptDTO.getBusinessType();
        Class<?> clazz = getBusinessClass(businessType);
        Class<?> tempClazz = getBusinessTempClass(businessType);
        List<String> corpidList = allScriptDTO.getCorpidList();
        if (corpidList.isEmpty()){
            corpidList = paasFormExplainModel.getCorpidList();
            corpidList.remove("0");
        }
        allScriptDTO.setCorpidList(corpidList);
        LOGGER.warn(corpidList.size() + "家公司");
        Map<String, Object> enumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Object[] objs = clazz.getEnumConstants();
        for (Object obj : objs) {
            try {
                String name = (String) clazz.getMethod("getAttr").invoke(obj);
                enumMap.put(name, obj);
            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
        Integer index = 1;
        for (String corpid : corpidList) {
            List<PaasFormExplainEntity> updateList = new ArrayList<>();
            List<Long> failList = new ArrayList<>();
            LOGGER.warn(index + "/" + allScriptDTO.getCorpidList().size());
            index++;
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("del", 0);
            param.put("businessType", businessType);
            if(allScriptDTO.getFormId() !=null) {
                param.put("formId", allScriptDTO.getFormId());
            }
            List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.list(param);
            for (PaasFormExplainEntity entity : paasFormExplainEntityList) {
                List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(entity.getExplains(), FieldAttrEntity.class);
                for (AllScriptDTO scriptDTO : allScriptDTOList) {
                    String attr = scriptDTO.getAttr();
                    String fieldAttr = scriptDTO.getFieldAttr();
                    String initMethod = scriptDTO.getInitMethod();
                    String initMethodField = scriptDTO.getInitMethodField();
                    String afterAttr = scriptDTO.getAfterAttr();
                    boolean insertFieldAttr = !attr.isEmpty();
                    RepairExplainEnum repairExplainEnum = RepairExplainEnum.getByCode(scriptDTO.getOperate());
                    switch (repairExplainEnum) {
                        case REPAIR:
                            boolean updateFieldAttr = !fieldAttr.isEmpty();
                            boolean updateFieldAttrList = CollectionUtils.isNotEmpty(scriptDTO.getFieldAttrList());
                            boolean updateInitMethod = !initMethod.isEmpty();
                            for (FieldAttrEntity fieldAttrEntity : fieldAttrEntityList) {
                                if (Objects.equals(attr, fieldAttrEntity.getAttr())) {
                                    if (updateFieldAttr) {
                                        String fieldAttrInvoke = fieldAttr.substring(0, 1).toUpperCase() + fieldAttr.substring(1);
                                        try {
                                            if (!enumMap.containsKey(attr)) {
                                                continue;
                                            }
                                            Object value = clazz.getMethod("get" + fieldAttrInvoke).invoke(enumMap.get(attr));
                                            Class<?> returnType = clazz.getMethod("get" + fieldAttrInvoke).getReturnType();
                                            Method method = FieldAttrEntity.class.getMethod("set" + fieldAttrInvoke, returnType);
                                            method.invoke(fieldAttrEntity, value);
                                        } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                                            e.printStackTrace();
                                        }
                                    } else if (updateFieldAttrList) {
                                        for (String updateField : scriptDTO.getFieldAttrList()) {
                                            String fieldAttrInvoke = updateField.substring(0, 1).toUpperCase() + updateField.substring(1);
                                            try {
                                                if (!enumMap.containsKey(attr)) {
                                                    continue;
                                                }
                                                Object value = clazz.getMethod("get" + fieldAttrInvoke).invoke(enumMap.get(attr));
                                                Class<?> returnType = clazz.getMethod("get" + fieldAttrInvoke).getReturnType();
                                                Method method = FieldAttrEntity.class.getMethod("set" + fieldAttrInvoke, returnType);
                                                method.invoke(fieldAttrEntity, value);
                                            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                                                e.printStackTrace();
                                            }
                                        }
                                    }
                                    if (updateInitMethod) {
                                        try {
                                            Method method = tempClazz.getMethod("init" + initMethod.substring(0, 1).toUpperCase() + initMethod.substring(1), FieldAttrEntity.class);
                                            InitExplainsHelper.commonFiledInit(fieldAttrEntity);
                                            FieldAttrEntity initEntity = new FieldAttrEntity();
                                            initEntity.setFieldType(fieldAttrEntity.getFieldType());
                                            method.invoke(tempClazz, initEntity);
                                            Method method1 = FieldAttrEntity.class.getMethod("get" + initMethodField.substring(0, 1).toUpperCase() + initMethodField.substring(1));
                                            Object value = method1.invoke(initEntity);
                                            Class<?> returnType = FieldAttrEntity.class.getMethod("get" + initMethodField.substring(0, 1).toUpperCase() + initMethodField.substring(1)).getReturnType();
                                            Method method2 = FieldAttrEntity.class.getMethod("set" + initMethodField.substring(0, 1).toUpperCase() + initMethodField.substring(1), returnType);
                                            method2.invoke(fieldAttrEntity, value);
                                        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                                            e.printStackTrace();
                                        }
                                    }
                                    if (!updateFieldAttr && !updateInitMethod && !updateFieldAttrList) {
                                        try {
                                            String saasAttr = fieldAttrEntity.getSaasAttr();
                                            Method method = tempClazz.getMethod("init" + saasAttr.substring(0, 1).toUpperCase() + saasAttr.substring(1), FieldAttrEntity.class);
                                            method.invoke(tempClazz, fieldAttrEntity);
                                        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                                            e.printStackTrace();
                                        }
                                    }
                                }
                            }
                            break;
                        case ADD:
                            Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(entity.getExplains(), null);
                            if (!explainMap.containsKey(attr)) {
                                for (int i = 0; i < fieldAttrEntityList.size(); i++) {
                                    //插入到当前字段后面
                                    FieldAttrEntity fieldAttrEntity = fieldAttrEntityList.get(i);
                                    if (Objects.equals(afterAttr, fieldAttrEntity.getAttr())) {
                                        if (insertFieldAttr) {
                                            try {
                                                // 包装业务枚举类;
                                                List<String> enumAttrs = null;
                                                if (enumAttrs == null) {
                                                    // 获取业务枚举类中的属性，以集合的形式返回，同一个枚举的属性值只获取一次
                                                    enumAttrs = InitExplainsHelper.getBusinessEnumAttrs(clazz);
                                                }
                                                Object obj = enumMap.get(attr);
                                                // 初始化字段解释
                                                FieldAttrEntity newFieldAttrEntity = InitExplainsHelper.setField(clazz, enumAttrs, obj);
                                                if (newFieldAttrEntity != null) {
                                                    String saasAttr = newFieldAttrEntity.getSaasAttr();
                                                    String initAttr = saasAttr.substring(0, 1).toUpperCase() + saasAttr.substring(1);
                                                    String methodName = "init" + initAttr;
                                                    try {
                                                        //这里拿到了新加入字段的初始化方法 并执行它 参数为 他的实例
                                                        Method methodHasParameter = tempClazz.getMethod(methodName, FieldAttrEntity.class);
                                                        methodHasParameter.invoke(tempClazz, newFieldAttrEntity);
                                                    } catch (NoSuchMethodException e) {
                                                        // 没有对应字段的初始化方法
                                                    } catch (Exception e) {
                                                        LOGGER.warn(e.getMessage());
                                                        throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
                                                    }
                                                    fieldAttrEntityList.add(i + 1, newFieldAttrEntity);
                                                }
                                            } catch (Exception e) {
                                                failList.add(entity.getId());
                                                e.printStackTrace();
                                            }
                                        }
                                    }
                                }
                            }
                            break;
                        default:
                            break;
                    }
                }
                entity.setExplains(JSON.toJSONString(fieldAttrEntityList));
                paasFormExplainModel.update(entity);
            }
        }
        return null;
    }

    @Override
    public ScriptVO fixProductForm(AllScriptDTO allScriptDTO) throws XbbException {
        Class clazz = ProductEnum.class;
        List<String> enumAttrs = InitExplainsHelper.getBusinessEnumAttrs(clazz);
        List<String> corpidList;
        if (Objects.nonNull(allScriptDTO.getCorpidList()) && !allScriptDTO.getCorpidList().isEmpty()){
            corpidList = allScriptDTO.getCorpidList();
        }else {
            corpidList = paasFormExplainModel.getCorpidList();
        }
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("businessType",XbbRefTypeEnum.PRODUCT.getCode());
        map.put("del",0);
        int i = 0;
        long start = DateTimeUtil.getInt();
        //预警详情
        FieldAttrEntity stockInfo = InitExplainsHelper.setField(clazz, enumAttrs, ProductEnum.STOCK_NOTIFY);
        TempProductEnum.initStockNotify(stockInfo);
        List<FieldAttrEntity> stockList = Collections.singletonList(stockInfo);
        //库存预警分割线，预警详情
        List<FieldAttrEntity> stockInfoList = Collections.singletonList(InitExplainsHelper.setField(clazz, enumAttrs, ProductEnum.STOCK_INFO));
        //仓库
        FieldAttrEntity warehouse = InitExplainsHelper.setField(clazz, enumAttrs, ProductEnum.WAREHOUSE);
        TempProductEnum.initWarehouse(warehouse);
        FieldAttrEntity warehouseHide = InitExplainsHelper.setField(clazz, enumAttrs, ProductEnum.WAREHOUSE_LINK_TEXT);
        //仓库分割线，仓库
        List<FieldAttrEntity> warehouseList = Arrays.asList(InitExplainsHelper.setField(clazz, enumAttrs, ProductEnum.WAREHOUSE_INFO),warehouse,warehouseHide);
        //sku启用
        List<FieldAttrEntity> skuEnableList = Collections.singletonList(InitExplainsHelper.setField(clazz, enumAttrs, ProductEnum.ENABLE_SKU));
        //规格信息 分割线
        List<FieldAttrEntity> specList = Collections.singletonList(InitExplainsHelper.setField(clazz, enumAttrs, ProductEnum.SPECIFICATION_INFO));
        //流水号
        FieldAttrEntity searalNo = InitExplainsHelper.setField(clazz, enumAttrs, ProductEnum.SERIALNO);
        TempProductEnum.initSerialNo(searalNo);
        List<FieldAttrEntity> serialNoList = Collections.singletonList(searalNo);
        FieldAttrEntity notify = InitExplainsHelper.setField(clazz, enumAttrs, ProductEnum.IS_NOTIFY);
        notify.setFieldType(ProductEnum.IS_NOTIFY.getFieldType());
        notify.setAttrName(ProductEnum.IS_NOTIFY.getAttrName());
        notify.setShowType(ProductEnum.IS_NOTIFY.getShowType());
        notify.setSetType(ProductEnum.IS_NOTIFY.getSetType());
        TempProductEnum.initIsNotify(notify);
        for (String corpid : corpidList){
            map.put("corpid",corpid);
            List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.findEntitys(map);
            LOGGER.warn("corpid:" + corpid + " : " + i + "/" + corpidList.size());
            i++;
            for (PaasFormExplainEntity entityExt : paasFormExplainEntityList){
                boolean stockBoolean = false;
                int stockIndex = 0;
                boolean stockLineBoolean = false;
                int stockLineIndex = 0;
                boolean warehouseBoolean = false;
                int warehouseIndex = 0;
                boolean skuBoolean = false;
                int skuIndex = 0;
                boolean specBoolean = false;
                int specIndex = 0;
                boolean serialBoolean = false;
                int serialIndex = 0;
                boolean hasNotify = false;
                List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(entityExt.getExplains(),FieldAttrEntity.class);
                Map<Integer,List<FieldAttrEntity>> indexMap = new LinkedHashMap<>();
                Map<Integer,List<FieldAttrEntity>> indexAfterMap = new LinkedHashMap<>();
                int index = 0;
                for (FieldAttrEntity entity : fieldAttrEntityList){
                    if (Objects.equals(entity.getAttr(),ProductEnum.STOCK.getAttr())){
                        //库存属性修改
                        entity.setFieldType(ProductEnum.STOCK.getFieldType());
                        entity.setShowType(ProductEnum.STOCK.getShowType());
                        entity.setShowEditable(0);
                        entity.setEditable(0);
                        entity.setDisableListSort(1);
                        entity.setForbiddenSettingList(Collections.singletonList(ForbiddenSettingEnum.DISABLE_MONEY_TYPE.getAlias()));
                    }else if (Objects.equals(entity.getAttr(),ProductEnum.IS_NOTIFY.getAttr())){
                        hasNotify = true;
                        //是否预警属性修改
                        entity.setFieldType(ProductEnum.IS_NOTIFY.getFieldType());
                        entity.setAttrName(ProductEnum.IS_NOTIFY.getAttrName());
                        entity.setShowType(ProductEnum.IS_NOTIFY.getShowType());
                        entity.setSetType(ProductEnum.IS_NOTIFY.getSetType());
                        TempProductEnum.initIsNotify(entity);
                        //新增预警详情分割线，下标是否启用
                        stockLineIndex = index;
                        indexMap.put(stockLineIndex,stockInfoList);
                        //新增预警详情，下标启用后
                        stockIndex = index;
                        indexAfterMap.put(stockIndex,stockList);
                    }else if (Objects.equals(entity.getAttr(),ProductEnum.SPECIFICATION.getAttr())){
                        //规格属性修改
                        entity.setSetType(ProductEnum.SPECIFICATION.getSetType());
                        TempProductEnum.initSpecification(entity);
                        //新增规格分割线，下标规格
                        specIndex = index;
                        indexMap.put(specIndex,specList);
                        //新增仓库信息，下标规格后
                        warehouseIndex = index;
                        indexAfterMap.put(warehouseIndex,warehouseList);
                    }else if (Objects.equals(entity.getAttr(),ProductEnum.PRODUCT_NO.getAttr())){
                        //原产品编号弃用
                        entity.setShowType(ProductEnum.PRODUCT_NO.getShowType());
                        entity.setSaasAttr(ProductEnum.PRODUCT_NO.getSaasAttr());
                        entity.setEditHide(ProductEnum.PRODUCT_NO.getEditHide());
                        //新的流水号，下标编号
                        serialIndex = index;
                        indexMap.put(serialIndex,serialNoList);
                    }else if (Objects.equals(entity.getAttr(),ProductEnum.TEMP_STOCK.getAttr())){
                        //新增sku是否启用，下标临时库存
                        skuIndex = index;
                        indexMap.put(skuIndex,skuEnableList);
                    }else if (Objects.equals(entity.getAttr(),ProductEnum.STOCK_NOTIFY.getAttr())){
                        stockBoolean = true;
                    }else if (Objects.equals(entity.getAttr(),ProductEnum.WAREHOUSE_INFO.getAttr())){
                        warehouseBoolean = true;
                    }else if (Objects.equals(entity.getAttr(),ProductEnum.WAREHOUSE.getAttr())){
                        warehouseBoolean = true;
                    }else if (Objects.equals(entity.getAttr(),ProductEnum.WAREHOUSE_LINK_TEXT.getAttr())){
                        warehouseBoolean = true;
                    }else if (Objects.equals(entity.getAttr(),ProductEnum.STOCK_INFO.getAttr())){
                        stockLineBoolean = true;
                    }else if (Objects.equals(entity.getAttr(),ProductEnum.ENABLE_SKU.getAttr())){
                        skuBoolean = true;
                    }else if (Objects.equals(entity.getAttr(),ProductEnum.SPECIFICATION_INFO.getAttr())){
                        specBoolean = true;
                    }else if (Objects.equals(entity.getAttr(),ProductEnum.SERIALNO.getAttr())){
                        serialBoolean = true;
                    }
                    index ++;
                }
                if (stockBoolean){
                    indexAfterMap.remove(stockIndex);
                }
                if (warehouseBoolean){
                    indexAfterMap.remove(warehouseIndex);
                }
                if (skuBoolean){
                    indexMap.remove(skuIndex);
                }
                if (specBoolean){
                    indexMap.remove(specIndex);
                }
                if (serialBoolean){
                    indexMap.remove(serialIndex);
                }
                if (stockLineBoolean){
                    indexMap.remove(stockLineIndex);
                }
                int indexMark = 0;
                for (Map.Entry<Integer,List<FieldAttrEntity>> entityEntry : indexMap.entrySet()){
                    List<FieldAttrEntity> newList = entityEntry.getValue();
                    Integer insertIndex = entityEntry.getKey();
                    insertIndex += indexMark;
                    fieldAttrEntityList.addAll(insertIndex,newList);
                    indexMark = indexMark + newList.size();
                }
                indexMark = 0;
                for (Map.Entry<Integer,List<FieldAttrEntity>> entityEntry : indexAfterMap.entrySet()){
                    List<FieldAttrEntity> newList = entityEntry.getValue();
                    Integer insertIndex = entityEntry.getKey();
                    insertIndex ++;
                    insertIndex += indexMark;
                    fieldAttrEntityList.addAll(insertIndex,newList);
                    indexMark = indexMark + newList.size();
                }
                if (!hasNotify){
                    fieldAttrEntityList.addAll(stockInfoList);
                    fieldAttrEntityList.add(notify);
                    fieldAttrEntityList.addAll(stockList);
                }
                entityExt.setExplains(JSONArray.toJSONString(fieldAttrEntityList));
                paasFormExplainModel.update(entityExt);
            }
        }
        LOGGER.warn("time consume:" + (DateTimeUtil.getInt() - start));
        LOGGER.warn("success");
        return null;
    }

    @Override
    public ScriptVO updateOwnerOrCoUser(AllScriptDTO allScriptDTO) throws XbbException {
        List<Integer> businessTypeList = allScriptDTO.getBusinessTypeList();
        allScriptDTO.setOperate(1);
        for (Integer businessType : businessTypeList) {
            allScriptDTO.setBusinessType(businessType);
            try {
                repairExplain(allScriptDTO);
            } catch (XbbException e) {

            }
        }
        return new ScriptVO();
    }

    @Override
    public ScriptVO fixDefaultForm(FixFormDTO fixFormDTO) throws XbbException {
        List<String> corpidList = Collections.singletonList("0");
        List<Integer> businessTypeList = Arrays.asList(XbbRefTypeEnum.BAD_DEBT.getCode(),XbbRefTypeEnum.PAY_SHEET.getCode(),XbbRefTypeEnum.PUSH_NOTIFY.getCode());
        LOGGER.info("Mantis Shrimp!Let we go");
        Integer total = businessTypeList.size();
        LOGGER.info("共计表单：" + total);
        Integer index = 1;
        for (String corpid : corpidList){
            for (Integer businessType : businessTypeList) {
                LOGGER.info("共计公司：" + index + "/" + total);
                index ++;
                Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid",corpid);
                param.put("businessType",businessType);
                List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.findEntitys(param);
                if (paasFormExplainEntityList.isEmpty()){
                    continue;
                }
                Class<?> clazz = getBusinessClass(businessType);
                Class<?> tempClazz = getBusinessTempClass(businessType);
                List<FieldAttrEntity> fieldAttrEntityList = new ArrayList<>();
                List<String> fieldAttrList = InitExplainsHelper.getBusinessEnumAttrs(clazz);
                Object[] objs = clazz.getEnumConstants();
                for (Object obj : objs) {
                    FieldAttrEntity fieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                    String saasAttr = "";
                    try {
                        for (String fieldAttr : fieldAttrList) {
                            String attr = fieldAttr.substring(0, 1).toUpperCase() + fieldAttr.substring(1);
                            Object value = clazz.getMethod("get" + attr).invoke(obj);
                            Class<?> returnType = clazz.getMethod("get" + attr).getReturnType();
                            Method method = FieldAttrEntity.class.getMethod("set" + attr, returnType);
                            method.invoke(fieldAttrEntity, value);
                            if (Objects.equals(fieldAttr, "saasAttr")) {
                                saasAttr = value.toString();
                            }
                            if (Objects.equals("fieldType",fieldAttr)) {
                                Integer fieldType = Integer.parseInt(value.toString());
                                String esAlias = FieldTypeEnum.getFieldTypeEnum(fieldType).getEsalias();
                                fieldAttrEntity.setAttrType(esAlias);
                            }
                            if (Objects.equals("attrName",fieldAttr)){
                                fieldAttrEntity.setDefaultName(value.toString());
                            }
                        }
                        Method method = tempClazz.getMethod("init" + saasAttr.substring(0, 1).toUpperCase() + saasAttr.substring(1), FieldAttrEntity.class);
                        InitExplainsHelper.commonFiledInit(fieldAttrEntity);
                        method.invoke(tempClazz, fieldAttrEntity);
                    } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                        e.printStackTrace();
                    }
                    fieldAttrEntityList.add(fieldAttrEntity);
                }
                for (PaasFormExplainEntity explainEntityExt : paasFormExplainEntityList){
                    explainEntityExt.setExplains(JSONArray.toJSONString(fieldAttrEntityList));
                    paasFormExplainModel.update(explainEntityExt);
                }
            }
        }
        return null;
    }

    @Override
    public ScriptVO fixWorkOrderForm(FixFormDTO fixFormDTO) throws XbbException {
        List<String> corpidList = paasFormExplainModel.getCorpidList();
//        List<String> corpidList = Collections.singletonList("1");
        LOGGER.info("Mantis Shrimp!Let we go");
        Integer total = corpidList.size();
        LOGGER.info("共计表单：" + total);
        Integer index = 1;
        for (String corpid : corpidList){
            LOGGER.info("共计公司：" + index + "/" + total);
            index ++;
            for (Integer businessType : fixFormDTO.getBusinessTypeList()) {
                Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid",corpid);
                List<WorkOrderExplainEntity> workOrderExplainEntityList = workOrderExplainModel.findEntitys(param);
                if (workOrderExplainEntityList.isEmpty()){
                    continue;
                }
                Class<?> clazz = getBusinessClass(businessType);
                Class<?> tempClazz = getBusinessTempClass(businessType);
                List<FieldAttrEntity> fieldAttrEntityList = new ArrayList<>();
                List<String> fieldAttrList = InitExplainsHelper.getBusinessEnumAttrs(clazz);
                Object[] objs = clazz.getEnumConstants();
                for (Object obj : objs) {
                    FieldAttrEntity fieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                    String saasAttr = "";
                    try {
                        for (String fieldAttr : fieldAttrList) {
                            String attr = fieldAttr.substring(0, 1).toUpperCase() + fieldAttr.substring(1);
                            Object value = clazz.getMethod("get" + attr).invoke(obj);
                            Class<?> returnType = clazz.getMethod("get" + attr).getReturnType();
                            Method method = FieldAttrEntity.class.getMethod("set" + attr, returnType);
                            method.invoke(fieldAttrEntity, value);
                            if (Objects.equals(fieldAttr, "saasAttr")) {
                                saasAttr = value.toString();
                            }
                            if (Objects.equals("fieldType",fieldAttr)) {
                                Integer fieldType = Integer.parseInt(value.toString());
                                String esAlias = FieldTypeEnum.getFieldTypeEnum(fieldType).getEsalias();
                                fieldAttrEntity.setAttrType(esAlias);
                            }
                            if (Objects.equals("attrName",fieldAttr)){
                                fieldAttrEntity.setDefaultName(value.toString());
                            }
                        }
                        Method method = tempClazz.getMethod("init" + saasAttr.substring(0, 1).toUpperCase() + saasAttr.substring(1), FieldAttrEntity.class);
                        InitExplainsHelper.commonFiledInit(fieldAttrEntity);
                        method.invoke(tempClazz, fieldAttrEntity);
                    } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                        e.printStackTrace();
                    }
                    fieldAttrEntityList.add(fieldAttrEntity);
                }
                for (WorkOrderExplainEntity explainEntityExt : workOrderExplainEntityList){
                    explainEntityExt.setExplains(JSONArray.toJSONString(fieldAttrEntityList));
                    workOrderExplainModel.update(explainEntityExt);
                }
            }
        }
        return null;
    }

    @Override
    public ScriptVO fixFormFieldDefaultName(FixFormDTO fixFormDTO) throws XbbException {
        LocaleContextHolder.setLocale(Locale.CHINA);
        String corpid = fixFormDTO.getCorpid();
        CompanyConfigEntity companyConfig = companyConfigModel.getByConfigAlias(CompanyConfigEnum.PC_I18N_PACK.getAlias(), corpid);
        if (!Objects.isNull(companyConfig)) {
            String lang = companyConfig.getConfigValue();
            String[] split = lang.split("_");
            LocaleContextHolder.setLocale(new Locale(split[0], split[1]));
        }
        // 30+1(工单)个表单
        List<Integer> businessTypeList = fixFormDTO.getBusinessTypeList();
        if (Objects.isNull(businessTypeList) || businessTypeList.isEmpty()) {
            businessTypeList = Arrays.asList(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), XbbRefTypeEnum.CONTRACT.getCode(), XbbRefTypeEnum.REFUND.getCode(),
                    XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), XbbRefTypeEnum.CONTACT.getCode(), XbbRefTypeEnum.CUSTOMER_COMMUNICATE.getCode(),
                    XbbRefTypeEnum.SUPPLIER_COMMUNICATE.getCode(), XbbRefTypeEnum.COMMUNICATE_PLAN.getCode(), XbbRefTypeEnum.WORKREPORT_DAILY.getCode(),
                    XbbRefTypeEnum.WORKREPORT_WEEKLY.getCode(), XbbRefTypeEnum.WORKREPORT_MONTHLY.getCode(), XbbRefTypeEnum.PAYMENT.getCode(),
                    XbbRefTypeEnum.PAY_PLAN.getCode(), XbbRefTypeEnum.INVOICE.getCode(), XbbRefTypeEnum.SUPPLIER.getCode(), XbbRefTypeEnum.PURCHASE.getCode(),
                    XbbRefTypeEnum.RETURNED_PURCHASE.getCode(), XbbRefTypeEnum.SUPPLIER_CONTACT.getCode(), XbbRefTypeEnum.ASSEMBLE.getCode(),
                    XbbRefTypeEnum.PURCHASE_INSTOCK.getCode(),XbbRefTypeEnum.REFUND_INSTOCK.getCode(),XbbRefTypeEnum.OTHER_INSTOCK.getCode(),XbbRefTypeEnum.RETURNED_MATERIEL_INSTOCK.getCode(),XbbRefTypeEnum.PRODUCTION_INSTOCK.getCode(),
                    XbbRefTypeEnum.CONTRACT_OUTSTOCK.getCode(),XbbRefTypeEnum.RETURNED_PURCHASE_OUTSTOCK.getCode(),XbbRefTypeEnum.OTHER_OUTSTOCK.getCode(),XbbRefTypeEnum.PRODUCTION_MATERIEL_OUTSTOCK.getCode(),XbbRefTypeEnum.WORK_ORDER_OUTSTOCK.getCode(),
                    XbbRefTypeEnum.INVENTORY.getCode(), XbbRefTypeEnum.TRANSFER.getCode(), XbbRefTypeEnum.BOM_BILL.getCode(), XbbRefTypeEnum.PRODUCTION_ORDER.getCode(),
                    XbbRefTypeEnum.PRODUCT.getCode(), XbbRefTypeEnum.WAREHOUSE.getCode(), XbbRefTypeEnum.PAYMENT_SHEET.getCode(),
                    XbbRefTypeEnum.PAY_SHEET.getCode(), XbbRefTypeEnum.STOCK_PRODUCT.getCode());
        }


        LOGGER.warn("Mantis Shrimp!Let we go");
        int total = businessTypeList.size();
        LOGGER.warn("共计表单：" + total);
        int index = 1;
        if ((businessTypeList.size() == 1 && !businessTypeList.contains(XbbRefTypeEnum.WORK_ORDER.getCode())) || businessTypeList.size() > 1)
        for (Integer businessType : businessTypeList) {
            LOGGER.warn("共计公司：" + index + "/" + total);
            index ++;
            Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid",corpid);
            param.put("businessType",businessType);
            List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.findEntitys(param);
            if (paasFormExplainEntityList.isEmpty()){
                continue;
            }
            List<PaasFormExplainEntity> updateList = new ArrayList<>();
            Class<?> clazz = getBusinessClass(businessType);
            Object[] objs = clazz.getEnumConstants();
            Map<String, Object> enumMap;
            try {
                enumMap = getClassEnumMap(objs, clazz);
            } catch (Exception e) {
                return null;
            }

            for (PaasFormExplainEntity entity : paasFormExplainEntityList) {
                List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(entity.getExplains(), FieldAttrEntity.class);
                boolean update;
                try {
                    update = updateFieldAttrEntityList(fieldAttrEntityList, enumMap, clazz);
                } catch (Exception e) {
                    return null;
                }

                if (update) {
                    entity.setExplains(JSONArray.toJSONString(fieldAttrEntityList));
                    updateList.add(entity);
                }
            }
            if (updateList.isEmpty()) {
//                throw new XbbException(ErrorCodeEnum.API_SUCCESS, "未找到更新内容");
            } else {
                for (PaasFormExplainEntity entity : updateList) {
                    paasFormExplainModel.update(entity);
                }
            }
        }

        if (businessTypeList.contains(XbbRefTypeEnum.WORK_ORDER.getCode())) {
            // 工单：表单字段默认名称
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            List<WorkOrderExplainEntity> workOrderExplainEntityList = workOrderExplainModel.findEntitys(param);
            if (workOrderExplainEntityList.isEmpty()) {
                return null;
            }
            List<WorkOrderExplainEntity> updateList = new ArrayList<>();
            Class<?> clazz = getBusinessClass(XbbRefTypeEnum.WORK_ORDER.getCode());
            Object[] objs = clazz.getEnumConstants();
            Map<String, Object> enumMap;
            try {
                enumMap = getClassEnumMap(objs, clazz);
            } catch (Exception e) {
                return null;
            }

            for (WorkOrderExplainEntity entity : workOrderExplainEntityList) {
                List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(entity.getExplains(), FieldAttrEntity.class);
                boolean update;
                try {
                    update = updateFieldAttrEntityList(fieldAttrEntityList, enumMap, clazz);
                } catch (Exception e) {
                    return null;
                }
                if (update) {
                    entity.setExplains(JSONArray.toJSONString(fieldAttrEntityList));
                    updateList.add(entity);
                }
            }
            if (updateList.isEmpty()) {
//                throw new XbbException(ErrorCodeEnum.API_SUCCESS, "未找到更新内容");
            } else {
                for (WorkOrderExplainEntity entity : updateList) {
                    workOrderExplainModel.update(entity);
                }
            }
        }
        return null;
    }

    /**
     * 获取枚举map:{attr: classEnum}
     */
    private Map<String, Object> getClassEnumMap(Object[] objs, Class<?> clazz) throws Exception {
        Map<String, Object> enumMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (Object obj : objs) {
            try {
                String name = (String) clazz.getMethod("getAttr").invoke(obj);
                enumMap.put(name, obj);
            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
        return enumMap;
    }

    /**
     * 获取是否需要更新字段名称默认值
     */
    private boolean updateFieldAttrEntityList(List<FieldAttrEntity> fieldAttrEntityList,
                                              Map<String, Object> enumMap, Class<?> clazz) throws Exception{
        boolean update = false;
        for (FieldAttrEntity fieldAttrEntity : fieldAttrEntityList) {
            if(!Objects.equals(fieldAttrEntity.getIsRedundant(), 0)) {
                continue;
            }

            if(!enumMap.containsKey(fieldAttrEntity.getAttr())) {
                continue;
            }
            try {
                Object value = clazz.getMethod("getAttrName").invoke(enumMap.get(fieldAttrEntity.getAttr()));
                fieldAttrEntity.setDefaultName(value.toString());
                update = true;
            } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
        return update;
    }

    @Override
    public FormExplainAddBatchVO fixStockForm(AllScriptDTO allScriptDTO) throws XbbException{
        PaasFormEntity formEntity = paasFormModel.getByBusinessType(allScriptDTO.getBusinessType(), allScriptDTO.getCorpid());
        FormExplainAddBatchDTO formExplainAddBatchDTO = new FormExplainAddBatchDTO();
        BeanUtil.copyProperties(allScriptDTO, formExplainAddBatchDTO);
        List<FormExplainAddDTO> formExplainList = new ArrayList<>();
        FormExplainAddDTO formExplainAddDTO = new FormExplainAddDTO();
        BeanUtil.copyProperties(formEntity, formExplainAddDTO);
        formExplainAddDTO.setFormId(formEntity.getId());
        String alias = XbbRefTypeEnum.getByCode(formEntity.getBusinessType()).getAlias();
        // 初始化方法获取字段列表
        PaasFormEntityExt productForm = paasFormModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(), allScriptDTO.getCorpid());
        FundSetTransitionPojo fundSetTransitionPojo = new FundSetTransitionPojo(allScriptDTO.getCorpid());
        List<FieldAttrEntity> fieldAttrEntityList = InitExplainsHelper.initFieldAttrEntity(alias, productForm, fundSetTransitionPojo, 0);
        PaasFormExplainEntity explain = paasFormExplainModel.getByBusinessType(allScriptDTO.getBusinessType(), allScriptDTO.getCorpid());
        if (Objects.nonNull(explain)) {
            explain.setExplains(JSON.toJSONString(fieldAttrEntityList));
            paasFormExplainModel.update(explain);
            return null;
        } else {
            formExplainAddDTO.setFormList(fieldAttrEntityList);
            formExplainList.add(formExplainAddDTO);
            formExplainAddBatchDTO.setFormExplainList(formExplainList);
            FormExplainAddBatchVO formExplainAddBatchVO = paasFormExplainService.addBatch(formExplainAddBatchDTO);
            return formExplainAddBatchVO;
        }
    }

    @Override
    public ScriptVO updatePaymentExplains(UpdatePaymentExplainsDTO updatePaymentExplainsDTO) throws XbbException {
        ScriptVO scriptVO=new ScriptVO();
        List<String> corpidList = updatePaymentExplainsDTO.getCorpidList();
        if ( CollectionsUtil.isEmpty(corpidList) ){
            corpidList = paasFormExplainModel.getCorpidList();
            corpidList.remove("0");
        }
        List<String> attrList = updatePaymentExplainsDTO.getAttrList();
        Integer businessType = updatePaymentExplainsDTO.getBusinessType();
        Class<?> clazz = getBusinessClass(businessType);
        Object[] objs = clazz.getEnumConstants();
        Map<String,Object> params=new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for ( String attr : attrList ) {
            for ( Object obj : objs ) {
                try {
                    String name = (String) clazz.getMethod("getAttr").invoke(obj);
                    if ( !Objects.equals(name, attr) ) {
                        continue;
                    }
                    params.put(name,obj);
                } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                    e.printStackTrace();
                }
            }
        }
        Integer count=0;
        Long startTime = DateTimeUtil.getInt();
        for ( String corpid : corpidList ) {
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("del", 0);
            param.put("businessType", businessType);
            List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.list(param);
            LOGGER.info("共"+paasFormExplainEntityList.size()+"条数据");
            for ( PaasFormExplainEntity paasFormExplainEntity : paasFormExplainEntityList ) {
                List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                for ( String attr : attrList ) {
                    for ( FieldAttrEntity fieldAttrEntity : fieldAttrEntityList ) {
                        if ( Objects.equals(fieldAttrEntity.getAttr(), attr) ) {
                            Object obj = params.get(attr);
                            if ( Objects.nonNull(obj) ) {
                                BeanUtil.copyProperties(obj, fieldAttrEntity);
                                if ( Objects.equals(PaymentEnum.STATUS.getAttr(), attr) && Objects.equals(XbbRefTypeEnum.PAYMENT.getCode(), businessType) ) {
                                    TempPaymentEnum.initStatus(fieldAttrEntity);
                                    fieldAttrEntity.setEditable(0);
                                    fieldAttrEntity.setItemBanDefault(BasicConstant.ONE);
                                } else if ( Objects.equals(PaymentEnum.BAD_AMOUNT.getAttr(), attr) && Objects.equals(XbbRefTypeEnum.PAYMENT.getCode(), businessType) ) {
                                    fieldAttrEntity.setShowEditable(0);
                                } else if ( Objects.equals(PaymentEnum.INVOICE_AMOUNT.getAttr(), attr) && Objects.equals(XbbRefTypeEnum.PAYMENT.getCode(), businessType) ) {
                                    fieldAttrEntity.setShowEditable(0);
                                } else if ( Objects.equals(PaymentEnum.UN_AMOUNT.getAttr(), attr) && Objects.equals(XbbRefTypeEnum.PAYMENT.getCode(), businessType) ) {
                                    fieldAttrEntity.setShowEditable(0);
                                } else if ( Objects.equals(PaymentEnum.REAL_AMOUNT.getAttr(), attr) && Objects.equals(XbbRefTypeEnum.PAYMENT.getCode(), businessType) ) {
                                    fieldAttrEntity.setShowEditable(0);
                                } else if (Objects.equals(PaymentEnum.OWNER_ID.getAttr(), attr) && Objects.equals(XbbRefTypeEnum.PAYMENT.getCode(), businessType)) {
                                    fieldAttrEntity.setScreenType(PaymentEnum.OWNER_ID.getScreenType());
                                }
                            }
                        }
                    }
                }

                paasFormExplainEntity.setExplains(JSONObject.toJSONString(fieldAttrEntityList));
                paasFormExplainModel.update(paasFormExplainEntity);
//                PaasFormEntityExt paasFormEntityExt=paasFormModel.getByBusinessType(businessType,corpid);
//                if ( Objects.equals(paasFormEntityExt.getName(),"回款管理") ){
//                    paasFormEntityExt.setName("回款计划");
//                    paasFormModel.update(paasFormEntityExt);
//                }
                count++;
                LOGGER.info("当前是第"+count+"条数据");

            }
        }
        String msg = "修改了" + count + "条数据";
        scriptVO.setMsg(msg);
        LOGGER.info("---更新应收款模版处理(主要是隐藏了回款状态的高级可编辑属性)脚本结束");
        Long endTime = DateTimeUtil.getInt();
        Long consumeTime = endTime - startTime;
        LOGGER.info("---耗时为："+ consumeTime);
        return scriptVO;
    }

    private Class<?> repairFundManagement(Integer businessType) throws XbbException {
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        switch (xbbRefTypeEnum) {
            case CONTRACT:
                return FundContractScriptEnum.class;
            case PAYMENT:
                return FundPaymentScriptEnum.class;
            default:
                throw new XbbException(TemplateErrorCodeEnum.API_ERROR_350006);
        }
    }

    @Override
    public ScriptVO updateContractExplains(UpdateFundManagemenExpalinstDTO updateFundManagemenExpalinstDTO) throws XbbException {
        ScriptVO scriptVO = new ScriptVO();
        List<String> corpidList = updateFundManagemenExpalinstDTO.getCorpidList();
        if ( CollectionsUtil.isEmpty(corpidList) ) {
            corpidList = paasFormExplainModel.getCorpidList();
            corpidList.remove("0");
        }
        Integer businessType = updateFundManagemenExpalinstDTO.getBusinessType();
        List<FundContractScriptEnum> list = FundContractScriptEnum.getAllEnum();

        Class<?> clazz = getBusinessClass(businessType);
        Object[] objs = clazz.getEnumConstants();
        Map<String, FundContractScriptEnum> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for ( FundContractScriptEnum fundContractScriptEnum : list ) {
            for ( Object obj : objs ) {
                try {
                    //需要修改的字段
                    String attr = fundContractScriptEnum.getContractEnum().getAttr();
                    String name = (String) clazz.getMethod("getAttr").invoke(obj);
                    if ( !Objects.equals(name, attr) ) {
                        continue;
                    }
                    params.put(name, fundContractScriptEnum);
                } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                    LOGGER.error("",e);
                }catch (Exception e){
                    LOGGER.error("",e);
                }
            }
        }
        Integer count = 0;
        List<FundContractScriptEnum> updateFundContractScriptEnum = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<FundContractScriptEnum> addFundContractScriptEnum = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        LOGGER.info("共有"+corpidList.size()+"家需要刷");
        for ( String corpid : corpidList ) {
            try {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", corpid);
                param.put("del", 0);
                param.put("businessType", businessType);
                List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.list(param);
                LOGGER.info("共有"+ corpid +"===="+paasFormExplainEntityList.size()+"条数据需要刷");
                for ( PaasFormExplainEntity paasFormExplainEntity : paasFormExplainEntityList ) {
                    List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                    Map<String, FieldAttrEntity> oldAttrMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    for ( FieldAttrEntity fieldAttrEntity : fieldAttrEntityList ) {
                        oldAttrMap.put(fieldAttrEntity.getAttr(),fieldAttrEntity);
                    }
                    updateFundContractScriptEnum.clear();
                    addFundContractScriptEnum.clear();
                    for ( FundContractScriptEnum fundContractScriptEnum : list ) {
                        FieldAttrEntity oldFieldAttrEntity = oldAttrMap.get(fundContractScriptEnum.getContractEnum().getAttr());
                        if ( Objects.isNull(oldFieldAttrEntity) ){
                            addFundContractScriptEnum.add(fundContractScriptEnum);
                        } else {
                            updateFundContractScriptEnum.add(fundContractScriptEnum);
                        }
                    }
                    //更新字段
                    for ( FundContractScriptEnum fundContractScriptEnum : updateFundContractScriptEnum ) {
                        String attr = fundContractScriptEnum.getContractEnum().getAttr();
                        for ( FieldAttrEntity fieldAttrEntity : fieldAttrEntityList ) {
                            if ( Objects.equals(fieldAttrEntity.getAttr(), attr) ) {
                                FundContractScriptEnum updateFundContractScriptAttrEnum = params.get(attr);
                                if ( Objects.nonNull(updateFundContractScriptAttrEnum) ) {
                                    BeanUtil.copyProperties(updateFundContractScriptAttrEnum.getContractEnum(), fieldAttrEntity);
//                                    if ( Objects.equals(updateFundContractScriptAttrEnum.getContractEnum(), ContractEnum.BAD_AMOUNT) ) {
//                                        fieldAttrEntity.setSort(9629);
//                                    }
//                                    if ( Objects.equals(updateFundContractScriptAttrEnum.getContractEnum(), ContractEnum.ADD_PAYMENT) ) {
//                                        fieldAttrEntity.setNumericalLimitsFlag(1);
//                                        fieldAttrEntity.setNumericalLimits(new NumericalLimitsPoJo(0D,50D));
//                                    }
//                                    if ( Objects.equals(updateFundContractScriptAttrEnum.getContractEnum().getFieldType(), FieldTypeEnum.LINK_FORM_BUTTON.getType()) ) {
//                                        if ( Objects.equals(updateFundContractScriptAttrEnum.getContractEnum(), ContractEnum.ADD_PAYMENT_SHEET) ) {
//                                            FundContractScriptEnum.initAddPaymentSheet(fieldAttrEntity);
//                                        }
//                                        } else if ( Objects.equals(updateFundContractScriptAttrEnum.getContractEnum(), ContractEnum.ADD_WRITE_OFF_PREPAYMENT) ) {
//                                            FundContractScriptEnum.initAddWriteOffPrepayment(fieldAttrEntity);
//                                        }
//                                    }
                                }
                            }
                        }
                    }
                    List<FieldAttrEntity> newFieldAttrEntityList = fieldAttrEntityList;
                    //新增字段
                    for ( FundContractScriptEnum fundContractScriptEnum : addFundContractScriptEnum ) {
                        ContractEnum contractEnum = fundContractScriptEnum.getContractEnum();
                        if ( Objects.nonNull(fundContractScriptEnum) ) {
                            FieldAttrEntity addFieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                            BeanUtil.copyProperties(contractEnum, addFieldAttrEntity);
//                            if ( Objects.equals(contractEnum.getFieldType(), FieldTypeEnum.LINK_FORM_BUTTON.getType()) ) {
//                                if ( Objects.equals(contractEnum, ContractEnum.ADD_PAYMENT_SHEET) ) {
//                                    FundContractScriptEnum.initAddPaymentSheet(addFieldAttrEntity);
//                                } else if ( Objects.equals(contractEnum, ContractEnum.ADD_WRITE_OFF_PREPAYMENT) ) {
//                                    FundContractScriptEnum.initAddWriteOffPrepayment(addFieldAttrEntity);
//                                }
//                            } else
                                if ( Objects.equals(contractEnum.getFieldType(), FieldTypeEnum.NUM.getType())) {
                                if ( Objects.equals(contractEnum, ContractEnum.BAD_AMOUNT) ) {
                                    FundContractScriptEnum.initAddBadAmount(addFieldAttrEntity);
                                }
                            }
                            newFieldAttrEntityList.add(addFieldAttrEntity);
                        }
                    }
                    paasFormExplainEntity.setExplains(JSONObject.toJSONString(newFieldAttrEntityList));
                    paasFormExplainModel.update(paasFormExplainEntity);
                    count++;
                    LOGGER.info("当前是第"+count+"条数据");
                }
            } catch (Exception e) {
                LOGGER.error("",e);
            }
        }
        String msg = "修改了" + count + "条数据";
        LOGGER.info(msg);
        scriptVO.setMsg(msg);
        return scriptVO;
    }

    /**
     * 修复应收款的数据，把历史被红冲回款金额的应收款需要加上红冲回款金额
     * @param updatePaymentDataDTO
     * @return
     * @throws XbbException
     */
    @Override
    public ScriptVO scriptPaymentData(UpdatePaymentDataDTO updatePaymentDataDTO) throws XbbException {
        ScriptVO scriptVO = new ScriptVO();
        String redisPrefix = "bad_payment_data_pre";
        String key = "bad_payment_data_pre";
        String isExist = paasRedisHelper.getValue(redisPrefix, key);
        if ( Objects.nonNull(isExist) ) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100021.getCode(),"操作过于频繁,请稍等再试");
        }
        try {
            paasRedisHelper.setValue(redisPrefix, key, 1, RedisConstant.TINY_DURATION);
            List<String> corpidList = updatePaymentDataDTO.getCorpidList();
            if ( CollectionsUtil.isEmpty(corpidList) ) {
                corpidList = companyModel.getCorpidList();
            }
            LOGGER.info("共有" + corpidList.size() + "家数据");
            Integer i = 0;
            for ( String corpid : corpidList ) {
                i++;
                LOGGER.info("现在是第" + i + "家公司");
                List<PaymentEntityExt> redPaymentEntityList = paymentModel.getRedPaymentList(corpid);
                List<Long> dataIdIn = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                Map<Long, Double> redPaymentMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                for ( PaymentEntityExt item : redPaymentEntityList ) {
                    JSONObject data = item.getData();
                    Long originId = FastJsonHelper.getLongOrDefaultFromFormData(data, PaymentEnum.ORIGIN_ID.getAttr(), 0L);
                    Double redAmount = getDoubleOrDefaultFromFormData(data, PaymentEnum.REAL_AMOUNT.getAttr(), 0D);
                    dataIdIn.add(originId);
                    Double redTotalAmount = redPaymentMap.get(originId);
                    if ( Objects.isNull(redTotalAmount) ) {
                        redTotalAmount = redAmount;
                    } else {
                        redTotalAmount = Arith.add(redTotalAmount, redAmount);
                    }
                    redPaymentMap.put(originId, redTotalAmount);
                }

                if ( CollectionsUtil.isEmpty(dataIdIn) ) {
                    continue;
                }
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid", corpid);
                param.put("idIn", dataIdIn);
                List<PaymentEntityExt> paymentEntityList = paymentModel.findEntitys(param);
                PaymentUpdateBatchDTO paymentUpdateBatchDTO = new PaymentUpdateBatchDTO();
                List<PaymentUpdateDTO> paymentUpdateList = new ArrayList<>();
                for ( PaasFormDataEntityExt item : paymentEntityList ) {
                    Long id = item.getId();
                    JSONObject data = item.getData();
                    PaymentUpdateDTO paymentUpdateDTO = new PaymentUpdateDTO();
                    paymentUpdateDTO.setId(id);
                    //实收金额
                    Double realAmount = getDoubleOrDefaultFromFormData(data, PaymentEnum.REAL_AMOUNT.getAttr(), 0D);
                    //未收金额
                    Double unAmount = getDoubleOrDefaultFromFormData(data, PaymentEnum.UN_AMOUNT.getAttr(), 0D);
                    //计划收款金额
                    Double planAmount = getDoubleOrDefaultFromFormData(data, PaymentEnum.AMOUNT.getAttr(), 0D);
                    //坏账金额
                    Double badAmount = getDoubleOrDefaultFromFormData(data, PaymentEnum.BAD_AMOUNT.getAttr(), 0D);
                    //红冲总金额
                    Double redTotalAmount = redPaymentMap.get(id) == null ? 0D : redPaymentMap.get(id);
                    JSONObject newData = new JSONObject();
                    //修复数据后的实收金额
                    Double amount = realAmount + redTotalAmount;
                    //修复数据后的未收金额
                    Double realUnAmount = unAmount - redTotalAmount;

                    newData.put(PaymentEnum.REAL_AMOUNT.getAttr(), amount);
                    newData.put(PaymentEnum.UN_AMOUNT.getAttr(), realUnAmount);
                    String status = PaymentStatusEnum.RECEIVABLES.getCode();
                    if ( Objects.equals(amount, planAmount) ) {
                        //已收款:实收金额==计划收款金额
                        status = PaymentStatusEnum.RECEIVABLES.getCode();
                    } else if ( amount < planAmount && realUnAmount > 0D && realUnAmount < planAmount && badAmount == 0D ) {
                        // 部分已收款:实收金额小于计划收款金额、未收金额大于零同时未收款小于计划金额，同时坏账金额等于零
                        status = PaymentStatusEnum.PARTIAL_RECEIPTS.getCode();
                    } else if ( amount < planAmount && realUnAmount == 0D && badAmount > 0D ) {
                        //部分坏账:实收大于0且小于计划收款金额，未收金额等于零，同时坏账金额大于零小于计划收款金额
                        status = PaymentStatusEnum.PARTIAL_BAD_DEBT.getCode();
                        newData.put(PaymentEnum.BAD_AMOUNT.getAttr(), badAmount);
                    } else if ( Objects.equals(amount, 0D) && Objects.equals(realUnAmount, planAmount) ) {
                        //未收款:实收金额等于零、未收金额等于计划金额
                        status = PaymentStatusEnum.UN_RECEIVABLES.getCode();
                    } else if ( amount <= 0D && Objects.equals(badAmount, planAmount) ) {
                        //已坏账:实收金额等于零、坏账金额等于计划金额
                        status = PaymentStatusEnum.BAD_DEBT.getCode();
                        newData.put(PaymentEnum.BAD_AMOUNT.getAttr(), badAmount);
                    }
                    newData.put(PaymentEnum.STATUS.getAttr(), status);
                    paymentUpdateDTO.setData(newData);
                    paymentUpdateList.add(paymentUpdateDTO);
                }
                paymentUpdateBatchDTO.setCorpid(corpid);
                paymentUpdateBatchDTO.setPaymenrUpdateList(paymentUpdateList);
                paymentService.updateBatch(paymentUpdateBatchDTO);
            }
            scriptVO.setMsg("共修改了" + i + "家公司的数据");
            paasRedisHelper.removeValue(redisPrefix, key);
        }catch (Exception e) {
            LOGGER.error("刷应收款数据异常", e);
            paasRedisHelper.removeValue(redisPrefix, key);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
        }
        return scriptVO;
    }

    /**
     * 修复合同数据的入口
     *
     * @param repairContractDataDTO
     * @return
     * @throws XbbException
     */
    @Override
    public ScriptVO scriptContractData(RepairContractDataDTO repairContractDataDTO) throws XbbException {
        ScriptVO scriptVO = new ScriptVO();
        if ( !Objects.equals(repairContractDataDTO.getBusinessType(), XbbRefTypeEnum.CONTRACT.getCode()) ){
            throw new XbbException(BusinessTypeErrorCodeEnum.API_ERROR_361001);
        }
        List<String> corpidList = repairContractDataDTO.getCorpidList();
        if ( CollectionsUtil.isEmpty(corpidList) ) {
            corpidList = companyModel.getCorpidList();
        }
        LOGGER.info("共有" + corpidList.size() + "家数据");
        Integer i = 0;
        for ( String corpid : corpidList ) {
            i++;
            LOGGER.info("现在是第" + i + "家公司");

            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.CORPID, corpid);
            param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            Integer totalCount = paymentSheetModel.getBadPaymentSheetCount(param);
            LOGGER.info("该公司数据库中共有" + totalCount + "条坏账回款单数据");
            int pageSize = 1000;
            int totalPage = (totalCount % pageSize == 0) ? (totalCount / pageSize) : (totalCount / pageSize) + 1;
            int lastPageSize = (totalCount % pageSize == 0) ? pageSize : (totalCount % pageSize);
            for ( int page = 0; page < totalPage; page++ ) {
                if ( page == totalPage - 1 ) {
                    param.put("pageNum", lastPageSize);
                } else {
                    param.put("pageNum", pageSize);
                }
                param.put("start", page * pageSize);
                List<PaymentSheetEntityExt> badPaymentSheetList = paymentSheetModel.getBadPaymentSheet(param);
                if ( badPaymentSheetList.isEmpty() ) {
                    continue;
                }
                Double badTatalAmount = 0D;
                Map<Long, Double> badTatalAmountMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                Set<Long> contractIdIn = new HashSet<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                for ( PaasFormDataEntityExt item : badPaymentSheetList ) {
                    JSONObject data = item.getData();
                    JSONArray jsonArray = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, PaymentSheetEnum.CONTRACT.getAttr(), new JSONArray());
                    Double amount = getDoubleOrDefaultFromFormData(data, PaymentSheetEnum.AMOUNT.getAttr(), 0D);
                    for ( Object idLong : jsonArray ) {
                        Long contractId = Long.valueOf(idLong.toString());
                        badTatalAmount = badTatalAmountMap.get(contractId) == null ? 0D : badTatalAmountMap.get(contractId);
                        badTatalAmount = Arith.add(badTatalAmount, amount);
                        badTatalAmountMap.put(contractId, badTatalAmount);
                        contractIdIn.add(contractId);
                    }
                }

                if ( CollectionsUtil.isNotEmpty(contractIdIn) ) {
                    //查询坏账回款单关联的合同
                    ContractUpdateBatchDTO contractUpdateBatchDTO = new ContractUpdateBatchDTO();
                    contractUpdateBatchDTO.setCorpid(corpid);
                    List<ContractUpdateDTO> contractUpdateList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    BoolQueryBuilder contractBoolQueryBuilder = boolQuery();
                    contractBoolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
                    contractBoolQueryBuilder.filter(termsQuery(BasicConstant.DATAID, contractIdIn));
                    List<String> fieldList = new ArrayList<>();
                    fieldList.add(FieldTypeEnum.DATAID.getAlias());
                    fieldList.add(FieldTypeEnum.UPDATETIME.getAlias());
                    List<PaasFormDataEntityExt> contractList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_CONTRACT, contractBoolQueryBuilder, PaasFormDataEntityExt.class, fieldList);
                    for ( PaasFormDataEntityExt contractItem : contractList ) {
                        ContractUpdateDTO contractUpdateDTO = new ContractUpdateDTO();
                        Double badAmount = badTatalAmountMap.get(contractItem.getDataId()) == null ? 0D : badTatalAmountMap.get(contractItem.getDataId());
                        contractUpdateDTO.setId(contractItem.getDataId());
                        JSONObject data = new JSONObject();
                        data.put(ContractEnum.BAD_AMOUNT.getAttr(), badAmount);
                        contractUpdateDTO.setData(data);
                        contractUpdateDTO.setUpdateTime(contractItem.getUpdateTime());
                        contractUpdateList.add(contractUpdateDTO);
                    }
                    contractUpdateBatchDTO.setContractUpdateList(contractUpdateList);
                    contractService.updateBatch(contractUpdateBatchDTO, false,false);
                }
            }
        }
        scriptVO.setMsg("共修改了" + i + "家公司的数据");
        return scriptVO;
    }

    @Override
    public ScriptVO scriptContractSerialNo(RepairContractDataDTO repairContractDataDTO) throws XbbException{
        ScriptVO scriptVO = new ScriptVO();
        if ( !Objects.equals(repairContractDataDTO.getBusinessType(), XbbRefTypeEnum.INVOICE.getCode())){
            throw new XbbException(BusinessTypeErrorCodeEnum.API_ERROR_361001);
        }
        List<String> corpidList = repairContractDataDTO.getCorpidList();
        if ( CollectionsUtil.isEmpty(corpidList) ) {
            corpidList = companyModel.getCorpidList();
        }
        LOGGER.info("共有" + corpidList.size() + "家数据");
        Integer i = 0;
        Map<Long,String> contractSerialNoMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long,String> paymentSerialNoMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if(CollectionsUtil.isNotEmpty(corpidList)) {
            for (String corpid : corpidList) {
                i++;
                LOGGER.info("现在是第" + i + "家公司");
                //查询金额明细
                Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                map.put("corpid", corpid);
                map.put("del", BasicConstant.ZERO);
                List<InvoiceRelationshipEntity> invoiceRelationshipEntityList = invoiceRelationshipModel.findEntitys(map);
                if (CollectionsUtil.isNotEmpty(invoiceRelationshipEntityList)) {
                    for (InvoiceRelationshipEntity invoiceRelationshipEntity : invoiceRelationshipEntityList) {
                        Long contractId = invoiceRelationshipEntity.getContractId();
                        Long paymentId = invoiceRelationshipEntity.getPaymentId();
                        if (contractSerialNoMap.containsKey(contractId)) {
                            String serialNo = contractSerialNoMap.getOrDefault(contractId, "");
                            invoiceRelationshipEntity.setContractNo(serialNo);
                        } else {
                            ContractEntityExt contractEntityExt = contractModel.getByKey(contractId, corpid);
                            String serialNo = "";
                            if (Objects.nonNull(contractEntityExt)) {
                                serialNo = contractEntityExt.getSerialNo();
                                contractSerialNoMap.put(contractId, serialNo);
                            }
                            invoiceRelationshipEntity.setContractNo(serialNo);
                        }
                        if (paymentSerialNoMap.containsKey(paymentId)) {
                            String serialNo = paymentSerialNoMap.getOrDefault(paymentId, "");
                            invoiceRelationshipEntity.setPaymentNo(serialNo);
                        } else {
                            PaymentEntityExt paymentEntityExt = paymentModel.getByKey(paymentId, corpid);
                            String serialNo = "";
                            if (Objects.nonNull(paymentEntityExt)) {
                                serialNo = paymentEntityExt.getSerialNo();
                                paymentSerialNoMap.put(paymentId, serialNo);
                            }
                            invoiceRelationshipEntity.setPaymentNo(serialNo);
                        }
                    }
                    //查询坏账回款单关联的合同
                    invoiceRelationshipModel.updateBatchSerialNo(invoiceRelationshipEntityList);
                }
            }
        }
        scriptVO.setMsg("共修改了" + i + "家公司的数据");
        return scriptVO;
    }

    @Override
    public ScriptVO scriptInvoiceRelationship(FixDataJobDTO fixDataJobDTO) throws XbbException{
        ScriptVO scriptVO = new ScriptVO();
        if ( !Objects.equals(fixDataJobDTO.getBusinessType(), XbbRefTypeEnum.INVOICE.getCode())){
            throw new XbbException(BusinessTypeErrorCodeEnum.API_ERROR_361001);
        }
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = companyModel.getCorpidList();
        }
        LOGGER.info("共有" + corpidList.size() + "家数据");
        Integer i = 0;
        Integer j = 0;
        if(CollectionsUtil.isNotEmpty(corpidList)) {
            for (String corpid : corpidList) {
                i++;
                LOGGER.info("现在是第" + i + "家公司");
                List<InvoiceEntityExt> invoiceList = invoiceModel.getAllInvoiceList(corpid);
                List<UpdateDataEntity> updateDataEntityList = new ArrayList<>();
                if (CollectionsUtil.isNotEmpty(invoiceList)) {
                    for (InvoiceEntityExt invoiceEntityExt : invoiceList) {
                        JSONObject data = invoiceEntityExt.getData();
                        if (Objects.nonNull(data)) {
                            boolean isUpdate = false;
                            if (!data.containsKey(InvoiceEnum.PAYMENT_RELATIONSHIP.getAttr())) {
                                data.put(InvoiceEnum.PAYMENT_RELATIONSHIP.getAttr(), PaymentRelationshipEnum.PAYMENT.getCode());
                                isUpdate = true;
                            }
                            if(data.containsKey(InvoiceEnum.PAYMENT_ID.getAttr())){
                                data.put(InvoiceEnum.PAYMENT_RELATIONSHIP.getAttr(), PaymentRelationshipEnum.PAYMENT.getCode());
                                isUpdate = true;
                            }
                            if(data.containsKey(InvoiceEnum.PAYMENT_SHEET_ID.getAttr())){
                                data.put(InvoiceEnum.PAYMENT_RELATIONSHIP.getAttr(), PaymentRelationshipEnum.PAYMENT_SHEET.getCode());
                                isUpdate = true;
                            }

                            /*if(!data.containsKey(InvoiceEnum.PAYMENT_ID.getAttr())){
                                data.put(InvoiceEnum.PAYMENT_ID.getAttr(), null);
                                isUpdate = true;
                            }
                            if (!data.containsKey(InvoiceEnum.PAYMENT_SHEET_ID.getAttr())) {
                                data.put(InvoiceEnum.PAYMENT_SHEET_ID.getAttr(), null);
                                isUpdate = true;
                            }*/
                            if (isUpdate) {
                                UpdateDataEntity updateDataEntity = ExplainUtil.getUpdateData(invoiceEntityExt.getId(), invoiceEntityExt.getData(), corpid);
                                //不更新updateTime
                                updateDataEntity.setUpdateTime(invoiceEntityExt.getUpdateTime());
                                updateDataEntityList.add(updateDataEntity);
                            }
                        }
                    }
                    try{
                        if(CollectionsUtil.isNotEmpty(updateDataEntityList)) {
                            invoiceModel.updateBatch(updateDataEntityList, corpid,false);
                        }
                    }catch (Exception e){
                        LOGGER.info("更新失败corpid:"+corpid+e.getStackTrace().toString());
                    }

                }
            }
        }
        scriptVO.setMsg("共修改了" + i + "家公司的数据");
        return scriptVO;
    }

    @Override
    public ScriptVO scriptApproveData(FixDataJobDTO fixDataJobDTO) throws XbbException{
        ScriptVO scriptVO = new ScriptVO();
        if ( !Objects.equals(fixDataJobDTO.getBusinessType(), XbbRefTypeEnum.INVOICE.getCode())){
            throw new XbbException(BusinessTypeErrorCodeEnum.API_ERROR_361001);
        }
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = companyModel.getCorpidList();
        }
        LOGGER.info("共有" + corpidList.size() + "家数据");
        Integer i = 0;
        if(CollectionsUtil.isNotEmpty(corpidList)) {
            for (String corpid : corpidList) {
                i++;
                LOGGER.info("现在是第" + i + "家公司");
                List<PaasProcessDataEntity> paasProcessDataEntities = paasProcessDataModel.getAllData(corpid,BasicConstant.ZERO);
                //List<UpdateDataEntity> updateDataEntityList = new ArrayList<>();
                if (CollectionsUtil.isNotEmpty(paasProcessDataEntities)) {
                    for (PaasProcessDataEntity paasProcessDataEntity : paasProcessDataEntities) {
                        JSONObject data = JSONObject.parseObject(paasProcessDataEntity.getData());
                        if (Objects.nonNull(data)) {
                            boolean isUpdate = false;
                            if (!data.containsKey(InvoiceEnum.PAYMENT_RELATIONSHIP.getAttr())) {
                                data.put(InvoiceEnum.PAYMENT_RELATIONSHIP.getAttr(), PaymentRelationshipEnum.PAYMENT.getCode());
                            }
                            if (!data.containsKey(InvoiceEnum.PAYMENT_ID.getAttr())) {
                                data.put(InvoiceEnum.PAYMENT_ID.getAttr(), null);
                            }
                            if (!data.containsKey(InvoiceEnum.PAYMENT_SHEET_ID.getAttr())) {
                                data.put(InvoiceEnum.PAYMENT_SHEET_ID.getAttr(), null);
                            }
                            paasProcessDataEntity.setData(data.toJSONString());
                        }
                    }
                    try{
                        if(CollectionsUtil.isNotEmpty(paasProcessDataEntities)) {
                            paasProcessDataModel.updateBatch(paasProcessDataEntities, corpid);
                        }
                    }catch (Exception e){
                        LOGGER.info("更新失败corpid:"+corpid+e.getStackTrace().toString());
                    }
                }
            }
        }
        scriptVO.setMsg("共修改了" + i + "家公司的数据");
        return scriptVO;
    }

    @Override
    public ScriptVO scriptInvoiceAmountData(RepairInvoiceAmountDTO repairInvoiceAmountDTO) throws XbbException {
        ScriptVO scriptVO = new ScriptVO();
        String paramCorpid = repairInvoiceAmountDTO.getParamCorpid();
        List<Long> linkIdList = repairInvoiceAmountDTO.getLinkIdList();
        //第一步查询合同
        Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, paramCorpid);
        param.put(ParameterConstant.DEL,DelEnum.NORMAL.getDel());
        param.put("isCancel",BasicConstant.ZERO);
        if (CollectionsUtil.isNotEmpty(linkIdList)) {
            param.put("contractIdIn", linkIdList);
        }
        List<InvoiceRelationshipEntity> invoiceRelationshipEntityList = invoiceRelationshipModel.findEntitys(param);
        //第一步查询出时间内所有发票
        Map<Long,Double> contractInvoicAmountMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long,Double> paymentInvoiceAmountMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long,Double> paymentSheetInvoiceAmountMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if(CollectionsUtil.isNotEmpty(invoiceRelationshipEntityList)) {
            for (InvoiceRelationshipEntity invoiceRelationshipEntity : invoiceRelationshipEntityList) {
                Long contractId = invoiceRelationshipEntity.getContractId();
                Long paymentId = invoiceRelationshipEntity.getPaymentId();
                Long paymentSheetId = invoiceRelationshipEntity.getPaymentSheetId();
                if(contractId > 0L && paymentId <=0L && paymentSheetId<=0){
                    saasSaveHelp.addMapNormal(contractInvoicAmountMap,contractId,invoiceRelationshipEntity.getMoney());
                }else if(contractId >0L && paymentId >0L && paymentSheetId<=0L){
                    saasSaveHelp.addMapNormal(contractInvoicAmountMap,contractId,invoiceRelationshipEntity.getMoney());
                    saasSaveHelp.addMapNormal(paymentInvoiceAmountMap,paymentId,invoiceRelationshipEntity.getMoney());
                }else if(paymentSheetId >0L && paymentId<=0L){
                    if(contractId > 0L) {
                        saasSaveHelp.addMapNormal(contractInvoicAmountMap, contractId, invoiceRelationshipEntity.getMoney());
                    }
                    saasSaveHelp.addMapNormal(paymentSheetInvoiceAmountMap,paymentSheetId,invoiceRelationshipEntity.getMoney());
                }
            }
        }
        List<Long> contractIdList = null;
        List<Long> paymentIdList = null;
        List<Long> paymentSheetIdList = null;
        if(contractInvoicAmountMap.size()>0) {
            contractIdList = new ArrayList<>(contractInvoicAmountMap.keySet());
        } else {
            contractIdList = linkIdList;
        }
        if(paymentInvoiceAmountMap.size()>0) {
            paymentIdList = new ArrayList<>(paymentInvoiceAmountMap.keySet());
        }
        if(paymentSheetInvoiceAmountMap.size()>0){
            paymentSheetIdList = new ArrayList<>(paymentSheetInvoiceAmountMap.keySet());
        }
        List<ContractEntityExt> contractEntityExtList = new ArrayList<>();
        List<PaymentEntityExt> paymentEntityExtList = new ArrayList<>();
        List<PaymentSheetEntityExt> paymentSheetEntityExtList = new ArrayList<>();
        if(CollectionUtils.isNotEmpty(contractIdList)) {
            contractEntityExtList = contractService.getContractListByIds(paramCorpid, contractIdList);
        }
        if(Objects.nonNull(paymentIdList)) {
            Map<String, Object> paymentParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            paymentParam.put(ParameterConstant.CORPID, paramCorpid);
            paymentParam.put(ParameterConstant.ID_IN,paymentIdList);
            paymentParam.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            paymentEntityExtList = paymentModel.findEntitys(paymentParam);
        }
        if(Objects.nonNull(paymentSheetIdList)){
            Map<String, Object> paymentParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            paymentParam.put(ParameterConstant.CORPID, paramCorpid);
            paymentParam.put(ParameterConstant.ID_IN,paymentSheetIdList);
            paymentParam.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            paymentSheetEntityExtList = paymentSheetModel.findEntitys(paymentParam);
        }
        List<UpdateDataEntity> contractUpdateList = new ArrayList<>();
        List<UpdateDataEntity> paymentUpdateList = new ArrayList<>();
        List<UpdateDataEntity> paymentSheetUpdateList = new ArrayList<>();
        for(ContractEntityExt contractEntityExt : contractEntityExtList){
            JSONObject data = contractEntityExt.getData();
            JSONObject newContractDataJson = new JSONObject();
            double amount = getDoubleOrDefaultFromFormData(data,ContractEnum.AMOUNT.getAttr(),0D);
            double unInvoiceAmount = Arith.sub(amount,contractInvoicAmountMap.getOrDefault(contractEntityExt.getId(),0D));
            newContractDataJson.put(ContractEnum.INVOICE_AMOUNT.getAttr(),contractInvoicAmountMap.getOrDefault(contractEntityExt.getId(),0D));
            newContractDataJson.put(ContractEnum.UN_INVOICE_AMOUNT.getAttr(),unInvoiceAmount);
            UpdateDataEntity contractUpdateEntity = ExplainUtil.getUpdateData(contractEntityExt.getId(), newContractDataJson, paramCorpid);
            contractUpdateEntity.setUpdateTime(contractEntityExt.getUpdateTime());
            contractUpdateList.add(contractUpdateEntity);
        }
        if(CollectionsUtil.isNotEmpty(contractUpdateList)) {
            contractModel.updateBatch(contractUpdateList, paramCorpid, true);
        }
        for(PaymentEntityExt paymentEntityExt: paymentEntityExtList){
            JSONObject newDataJson = new JSONObject();
            newDataJson.put(PaymentEnum.INVOICE_AMOUNT.getAttr(),paymentInvoiceAmountMap.getOrDefault(paymentEntityExt.getId(),0D));
            UpdateDataEntity paymentUpdateEntity = ExplainUtil.getUpdateData(paymentEntityExt.getId(), newDataJson, paramCorpid);
            paymentUpdateEntity.setUpdateTime(paymentEntityExt.getUpdateTime());
            paymentUpdateList.add(paymentUpdateEntity);
        }
        if(CollectionsUtil.isNotEmpty(paymentUpdateList)) {
            paymentModel.updateBatch(paymentUpdateList, paramCorpid, true);
        }
        Set<String> uuids= new HashSet<>();
        HashMap<String,Double> parentInvoiceAmountMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for(PaymentSheetEntityExt paymentSheetEntityExt : paymentSheetEntityExtList){
            JSONObject sonPaymentSheetJson = new JSONObject();
            sonPaymentSheetJson.put(PaymentSheetEnum.INVOICE_AMOUNT.getAttr(),paymentSheetInvoiceAmountMap.getOrDefault(paymentSheetEntityExt.getId(),0D));
            UpdateDataEntity paymentSheetUpdateEntity = ExplainUtil.getUpdateData(paymentSheetEntityExt.getId(), sonPaymentSheetJson, paramCorpid);
            paymentSheetUpdateEntity.setUpdateTime(paymentSheetEntityExt.getUpdateTime());
            paymentSheetUpdateList.add(paymentSheetUpdateEntity);
            if(Objects.equals(paymentSheetEntityExt.getAlone(),SheetAloneEnum.CHILD.getCode())){
                uuids.add(paymentSheetEntityExt.getUuid());
                saasSaveHelp.addMapTwoInvoiceAmount(parentInvoiceAmountMap,paymentSheetEntityExt.getUuid(),paymentSheetInvoiceAmountMap.getOrDefault(paymentSheetEntityExt.getId(),0D));
            }
        }
        List<PaasFormDataEntityExt> parentAndChildEsDataList = fundHelp.getParentAndChildEsDataListByUuids(IndexTypeEnum.IDX_SAAS_PAYMENT_SHEET, paramCorpid, uuids);
        if(CollectionsUtil.isNotEmpty(parentAndChildEsDataList)){
            for(PaasFormDataEntityExt paasFormDataEntityExt : parentAndChildEsDataList){
                if(Objects.equals(paasFormDataEntityExt.getAlone(), SheetAloneEnum.PARENT.getCode())){
                    JSONObject parentPaymentSheetJson = new JSONObject();
                    parentPaymentSheetJson.put(PaymentSheetEnum.INVOICE_AMOUNT.getAttr(),parentInvoiceAmountMap.getOrDefault(paasFormDataEntityExt.getUuid(),0D));
                    UpdateDataEntity paymentSheetUpdateEntity = ExplainUtil.getUpdateData(paasFormDataEntityExt.getId(), parentPaymentSheetJson, paramCorpid);
                    paymentSheetUpdateEntity.setUpdateTime(paasFormDataEntityExt.getUpdateTime());
                    paymentSheetUpdateList.add(paymentSheetUpdateEntity);
                }
            }
        }
        if(CollectionsUtil.isNotEmpty(paymentSheetUpdateList)){
            paymentSheetModel.updateBatch(paymentSheetUpdateList, paramCorpid, true);
        }
        return scriptVO;
    }

    @Override
    public ScriptVO repairInvoiceRelationshipMoney(RepairInvoiceAmountDTO repairInvoiceAmountDTO) throws XbbException {
        ScriptVO scriptVO = new ScriptVO();
        List<Long> linkIdList = repairInvoiceAmountDTO.getLinkIdList();
        String paramCorpid = repairInvoiceAmountDTO.getParamCorpid();
        //第一步查询发票关联关系表内金额为0的异常数据
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, paramCorpid);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("type", BasicConstant.ZERO);
        param.put("money", BasicConstant.ZERO);
        if (CollectionsUtil.isNotEmpty(linkIdList)) {
            param.put("invoiceIdIn", linkIdList);
        }
        param.put("orderByStr", "id");
        Map<String, Object> paramInvoice = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        paramInvoice.put(ParameterConstant.CORPID, paramCorpid);
        paramInvoice.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        List<InvoiceRelationshipEntity> updateList = new ArrayList<>();
        while (true) {
            List<InvoiceRelationshipEntity> list = invoiceRelationshipModel.findEntitys(param);
            if (list == null || list.isEmpty()) {
                break;
            }
            InvoiceRelationshipEntity relationshipEntity = list.get(list.size() - 1);
            param.put("idGte", relationshipEntity.getId());
            //第二步查询这批异常relationship对应的发票
            Set<Long> invoiceIdIn = new HashSet<>();
            Map<Long, List<InvoiceRelationshipEntity>> mapRelationship = new HashMap<>(list.size());
            for (InvoiceRelationshipEntity entity : list) {
                Long invoiceId = entity.getInvoiceId();
                List<InvoiceRelationshipEntity> tempList = mapRelationship.get(invoiceId);
                if (Objects.isNull(tempList)) {
                    invoiceIdIn.add(invoiceId);
                    tempList = new ArrayList<>();
                } else {
                    //只处理一条明细的数据，多条明细无法追溯各个明细的开票金额
                    invoiceIdIn.remove(invoiceId);
                }
                tempList.add(entity);
                mapRelationship.put(invoiceId, tempList);
            }
            if (CollectionUtils.isEmpty(invoiceIdIn)) {
                continue;
            }
            paramInvoice.put("idIn", invoiceIdIn);
            List<InvoiceEntityExt> invoiceList = invoiceModel.findEntitys(paramInvoice);
            if (CollectionUtils.isEmpty(invoiceList)) {
                continue;
            }
            Map<Long, InvoiceEntityExt> mapInvoice = invoiceList.stream().collect(Collectors.toMap(i -> i.getId(), Function.identity()));
            for (Map.Entry<Long, List<InvoiceRelationshipEntity>> entry : mapRelationship.entrySet()) {
                List<InvoiceRelationshipEntity> relationshipList = entry.getValue();
                if (relationshipList.size() > BasicConstant.ONE) {
                    continue;
                }
                Long invoiceId = entry.getKey();
                InvoiceEntityExt invoiceEntityExt = mapInvoice.get(invoiceId);
                if (Objects.isNull(invoiceEntityExt)) {
                    continue;
                }
                JSONObject data = JsonHelperUtil.getJSONObject(invoiceEntityExt.getData());
                InvoiceRelationshipEntity invoiceRelationshipEntity = relationshipList.get(0);
                invoiceRelationshipEntity.setMoney(data.getDoubleValue(InvoiceEnum.TOTAL_MONEY.getAttr()));
                updateList.add(invoiceRelationshipEntity);
            }
        }
        if (updateList.size() > BasicConstant.ZERO) {
            invoiceRelationshipModel.updateBatchMoney(paramCorpid, updateList);
        }
        return scriptVO;
    }

    @Override
    public ScriptVO repairPurchaseInvoiceRelationshipMoney(RepairInvoiceAmountDTO repairInvoiceAmountDTO) throws XbbException {
        ScriptVO scriptVO = new ScriptVO();
        List<Long> linkIdList = repairInvoiceAmountDTO.getLinkIdList();
        String paramCorpid = repairInvoiceAmountDTO.getParamCorpid();
        //第一步查询发票关联关系表内金额为0的异常数据
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(ParameterConstant.CORPID, paramCorpid);
        param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("type", BasicConstant.ZERO);
        param.put("money", BasicConstant.ZERO);
        if (CollectionsUtil.isNotEmpty(linkIdList)) {
            param.put("purchaseInvoiceIdIn", linkIdList);
        }
        param.put("orderByStr", "id");
        Map<String, Object> paramInvoice = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        paramInvoice.put(ParameterConstant.CORPID, paramCorpid);
        paramInvoice.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        List<PurchaseInvoiceRelationshipEntity> updateList = new ArrayList<>();
        while (true) {
            List<PurchaseInvoiceRelationshipEntity> list = purchaseInvoiceRelationshipModel.findEntitys(param);
            if (list == null || list.isEmpty()) {
                break;
            }
            PurchaseInvoiceRelationshipEntity relationshipEntity = list.get(list.size() - 1);
            param.put("idGte", relationshipEntity.getId());
            //第二步查询这批异常relationship对应的发票
            Set<Long> invoiceIdIn = new HashSet<>();
            Map<Long, List<PurchaseInvoiceRelationshipEntity>> mapRelationship = new HashMap<>(list.size());
            for (PurchaseInvoiceRelationshipEntity entity : list) {
                Long invoiceId = entity.getPurchaseInvoiceId();
                List<PurchaseInvoiceRelationshipEntity> tempList = mapRelationship.get(invoiceId);
                if (Objects.isNull(tempList)) {
                    invoiceIdIn.add(invoiceId);
                    tempList = new ArrayList<>();
                } else {
                    //只处理一条明细的数据，多条明细无法追溯各个明细的开票金额
                    invoiceIdIn.remove(invoiceId);
                }
                tempList.add(entity);
                mapRelationship.put(invoiceId, tempList);
            }
            if (CollectionUtils.isEmpty(invoiceIdIn)) {
                continue;
            }
            paramInvoice.put("idIn", invoiceIdIn);
            List<PurchaseInvoiceEntityExt> invoiceList = purchaseInvoiceModel.findEntitys(paramInvoice);
            if (CollectionUtils.isEmpty(invoiceList)) {
                continue;
            }
            Map<Long, PurchaseInvoiceEntityExt> mapInvoice = invoiceList.stream().collect(Collectors.toMap(i -> i.getId(), Function.identity()));
            for (Map.Entry<Long, List<PurchaseInvoiceRelationshipEntity>> entry : mapRelationship.entrySet()) {
                List<PurchaseInvoiceRelationshipEntity> relationshipList = entry.getValue();
                if (relationshipList.size() > BasicConstant.ONE) {
                    continue;
                }
                Long invoiceId = entry.getKey();
                PurchaseInvoiceEntityExt invoiceEntityExt = mapInvoice.get(invoiceId);
                if (Objects.isNull(invoiceEntityExt)) {
                    continue;
                }
                JSONObject data = JsonHelperUtil.getJSONObject(invoiceEntityExt.getData());
                PurchaseInvoiceRelationshipEntity invoiceRelationshipEntity = relationshipList.get(0);
                invoiceRelationshipEntity.setMoney(data.getDoubleValue(PurchaseInvoiceEnum.TOTAL_MONEY.getAttr()));
                updateList.add(invoiceRelationshipEntity);
            }
        }
        if (updateList.size() > BasicConstant.ZERO) {
            purchaseInvoiceRelationshipModel.updateBatchMoney(paramCorpid, updateList);
        }
        return scriptVO;
    }

    @Override
    public ScriptVO repairInvoiceRelationshipSpecialMoney(RepairInvoiceRelationMoneyDTO repairInvoiceRelationMoneyDTO) throws XbbException {
        ScriptVO scriptVO = new ScriptVO();
        String paramCorpid = repairInvoiceRelationMoneyDTO.getCorpid();
        Double money = repairInvoiceRelationMoneyDTO.getMoney();
        Long key = repairInvoiceRelationMoneyDTO.getRelationId();
        Integer businessType = repairInvoiceRelationMoneyDTO.getBusinessType();
        if(Objects.equals(XbbRefTypeEnum.INVOICE.getCode(),businessType)){
            InvoiceRelationshipEntity entity = invoiceRelationshipModel.getByKey(key, paramCorpid);
            if (Objects.nonNull(entity) && Objects.nonNull(money)){
                entity.setMoney(money);
                invoiceRelationshipModel.update(entity);
            }
        }else if(Objects.equals(XbbRefTypeEnum.PURCHASE_INVOICE.getCode(),businessType)) {
            PurchaseInvoiceRelationshipEntity entity = purchaseInvoiceRelationshipModel.getByKey(key, paramCorpid);
            if (Objects.nonNull(entity) && Objects.nonNull(money)){
                entity.setMoney(money);
                purchaseInvoiceRelationshipModel.update(entity);
            }
        }
        return scriptVO;
    }

    @Override
    public ScriptVO repairBatchInvoiceRelationshipMoney(RepairInvoiceRelationMoneyDTO repairInvoiceRelationMoneyDTO) throws XbbException {
        ScriptVO scriptVO = new ScriptVO();
        String paramCorpid = repairInvoiceRelationMoneyDTO.getCorpid();
        Map<Long, Double> relateIdToMoneyMap = repairInvoiceRelationMoneyDTO.getRelateIdToMoneyMap();
        Integer businessType = repairInvoiceRelationMoneyDTO.getBusinessType();
        if(MapUtils.isEmpty(relateIdToMoneyMap)){
            return scriptVO;
        }
        List<InvoiceRelationshipEntity> updateInvoiceList = new ArrayList<>();
        List<PurchaseInvoiceRelationshipEntity> updatePurchaseInvoiceList = new ArrayList<>();
        for(Map.Entry<Long,Double> entry : relateIdToMoneyMap.entrySet()){
            if(Objects.equals(XbbRefTypeEnum.INVOICE.getCode(),businessType)){
                InvoiceRelationshipEntity invoiceRelationshipEntity = new InvoiceRelationshipEntity();
                invoiceRelationshipEntity.setId(entry.getKey());
                invoiceRelationshipEntity.setMoney(entry.getValue());
                updateInvoiceList.add(invoiceRelationshipEntity);
            }else if(Objects.equals(XbbRefTypeEnum.PURCHASE_INVOICE.getCode(),businessType)) {
                PurchaseInvoiceRelationshipEntity purchaseInvoiceRelationshipEntity = new PurchaseInvoiceRelationshipEntity();
                purchaseInvoiceRelationshipEntity.setId(entry.getKey());
                purchaseInvoiceRelationshipEntity.setMoney(entry.getValue());
                updatePurchaseInvoiceList.add(purchaseInvoiceRelationshipEntity);
            }
        }
        if(CollectionsUtil.isNotEmpty(updateInvoiceList)){
            invoiceRelationshipModel.updateBatchMoney(paramCorpid,updateInvoiceList);
        }
        if(CollectionsUtil.isNotEmpty(updatePurchaseInvoiceList)){
            purchaseInvoiceRelationshipModel.updateBatchMoney(paramCorpid,updatePurchaseInvoiceList);
        }
        return scriptVO;
    }


    @Override
    public ScriptVO scriptContractInvoiceAmountData(RepairContractBadAmountDTO repairContractBadAmountDTO) throws XbbException {
        ScriptVO scriptVO = new ScriptVO();
        if (!Objects.equals(repairContractBadAmountDTO.getBusinessType(), XbbRefTypeEnum.INVOICE.getCode())) {
            throw new XbbException(BusinessTypeErrorCodeEnum.API_ERROR_361001);
        }
        List<String> corpidList = repairContractBadAmountDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = companyModel.getCorpidList();
        }
        LOGGER.info("共有" + corpidList.size() + "家数据");
        Integer i = 0;
        if (CollectionsUtil.isNotEmpty(corpidList)) {
            for (String corpid : corpidList) {
                i++;
                LOGGER.info("现在是第" + i + "家公司");
                //第一步查询所有的合同
                int pageSize = 100;
                Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(ParameterConstant.CORPID,corpid);
                param.put(ParameterConstant.DEL,DelEnum.NORMAL.getDel());
                if(StringUtil.isNotEmpty(repairContractBadAmountDTO.getEndTime()) && StringUtil.isNotEmpty(repairContractBadAmountDTO.getStartTime())){
                    String fundTime = "2020-01-14 00:00:00";
                    int fundTimeStart= DateUtil.getInt(fundTime,DateUtil.SDF);
                    if(DateUtil.getInt(repairContractBadAmountDTO.getStartTime()) < fundTimeStart){
                        CommentUtil.addToMap(param, "startTime", fundTimeStart);
                    }
                    CommentUtil.addToMap(param, "startTime", DateUtil.getInt(repairContractBadAmountDTO.getStartTime()));
                    CommentUtil.addToMap(param, "endTime", DateUtil.getInt(repairContractBadAmountDTO.getEndTime()));
                }else {
                    //资金一期 和一期前逻辑不一样 暂时只支持一期之后
                    break;
                }
                List<Long> contractIdList = new ArrayList<>();
                Map<Long,Double> contractInvoiceAmountMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                List<ContractEntityExt> contractEntityExtList = contractModel.findEntitys(param);
                if(CollectionsUtil.isNotEmpty(contractEntityExtList)){
                    for(ContractEntityExt contractEntityExt : contractEntityExtList){
                        Long id = contractEntityExt.getId();
                        contractIdList.add(id);
                    }
                }

                param.put("contractIdIn",contractIdList);
                param.put("isCancel",BasicConstant.ZERO);
                List<InvoiceRelationshipEntity> invoiceRelationshipEntityList = invoiceRelationshipModel.findEntitys(param);
                if(CollectionsUtil.isNotEmpty(invoiceRelationshipEntityList)){
                    for(InvoiceRelationshipEntity invoiceRelationshipEntity : invoiceRelationshipEntityList){
                        saasSaveHelp.addMapNormal(contractInvoiceAmountMap,invoiceRelationshipEntity.getContractId(),invoiceRelationshipEntity.getMoney());
                    }
                }
                List<UpdateDataEntity> contractUpdateList = new ArrayList<>();
                if(CollectionsUtil.isNotEmpty(contractEntityExtList)) {
                    for (ContractEntityExt contractEntityExt : contractEntityExtList) {
                        Long id = contractEntityExt.getId();
                        JSONObject data = contractEntityExt.getData();
                        double totalMoney = getDoubleOrDefaultFromFormData(data,ContractEnum.AMOUNT.getAttr(),0D);
                        double invoiceAmount = contractInvoiceAmountMap.getOrDefault(id, 0D);
                        data.put(ContractEnum.INVOICE_AMOUNT.getAttr(), invoiceAmount);
                        data.put(ContractEnum.UN_INVOICE_AMOUNT.getAttr(), Arith.sub(totalMoney, invoiceAmount));
                        UpdateDataEntity contractUpdateEntity = ExplainUtil.getUpdateData(id, data, corpid);
                        contractUpdateEntity.setUpdateTime(contractEntityExt.getUpdateTime());
                        contractUpdateList.add(contractUpdateEntity);
                    }
                }
                if(CollectionsUtil.isNotEmpty(contractUpdateList)) {
                    contractModel.updateBatch(contractUpdateList, corpid, false);
                }
            }
        }
        scriptVO.setMsg("总共更新" + i + "家合同数据");
        return scriptVO;
    }

    @Override
    public ScriptVO scriptContractBadAmount(RepairContractBadAmountDTO repairContractBadAmountDTO) throws XbbException {
        ScriptVO scriptVO = new ScriptVO();
        List<String> corpidList = repairContractBadAmountDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = companyModel.getCorpidList();
        }
        LOGGER.info("共有" + corpidList.size() + "家数据");
        Integer i = 0;
        for (String corpid : corpidList) {
            i++;
            LOGGER.info("现在是第" + i + "家公司");
            int pageSize = 100;
            Long idGte = 0L;
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.CORPID, corpid);
            param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            if ( StringUtil.isEmpty(repairContractBadAmountDTO.getEndTime()) ) {
                Map<String,Object> paramLimit= new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                paramLimit.put("pageSize", 1);
                paramLimit.put(ParameterConstant.CORPID, corpid);
                paramLimit.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
                List<ContractEntityExt> contractEntityExtListLimit = contractModel.findEntitys(paramLimit);
                if ( CollectionsUtil.isEmpty(contractEntityExtListLimit) ) {
                    continue;
                }
                ContractEntityExt oldContractEntityExt =contractEntityExtListLimit.get(0);
                JSONObject oldData = oldContractEntityExt.getData();
                Double badAmount = getDoubleFromFormData(oldData, ContractEnum.BAD_AMOUNT.getAttr());
                if ( badAmount !=null ) {
                    continue;
                }
                Boolean flag = true;
                int j = 0;
                while (flag) {
                    LOGGER.info("当前是" + j++ + "页");
                    param.put("pageSize", pageSize);
                    param.put("orderByStr", "id asc");
                    param.put("idGte", idGte);
                    List<ContractEntityExt> contractEntityExtList = contractModel.findEntitys(param);
                    if ( contractEntityExtList.isEmpty() ) {
                        flag = false;
                        continue;
                    }
                    idGte = updateContractData(contractEntityExtList,corpid);
                }
            } else {
                Integer totalCount = contractModel.getEntitysCount(param);
                LOGGER.info("该公司数据库中共有" + totalCount + "条合同数据");
                int totalPage = (totalCount % pageSize == 0) ? (totalCount / pageSize) : (totalCount / pageSize) + 1;
                int lastPageSize = (totalCount % pageSize == 0) ? pageSize : (totalCount % pageSize);
                for (int page = 0; page < totalPage; page++) {
                    if ( page == totalPage - 1 ) {
                        param.put("pageNum", lastPageSize);
                    } else {
                        param.put("pageNum", pageSize);
                    }
                    param.put("start", page * pageSize);
                    if ( StringUtil.isNotEmpty(repairContractBadAmountDTO.getStartTime()) ) {
                        CommentUtil.addToMap(param, "startTime", DateUtil.getInt(repairContractBadAmountDTO.getStartTime()));
                    }
                    if ( StringUtil.isNotEmpty(repairContractBadAmountDTO.getEndTime()) ) {
                        CommentUtil.addToMap(param, "endTime", DateUtil.getInt(repairContractBadAmountDTO.getEndTime()));
                    }
                    List<ContractEntityExt> contractEntityExtList = contractModel.findEntitys(param);
                    if (contractEntityExtList.isEmpty()) {
                        continue;
                    }
                    updateContractData(contractEntityExtList,corpid);
                }
            }
        }
        scriptVO.setMsg("总共更新" + i + "家合同数据");
        return scriptVO;
    }

    private Long updateContractData(List<ContractEntityExt> contractEntityExtList,String corpid) throws XbbException {
        Long idGte = 0L;
        ContractUpdateBatchDTO contractUpdateBatchDTO = new ContractUpdateBatchDTO();
        contractUpdateBatchDTO.setCorpid(corpid);
        List<ContractUpdateDTO> contractUpdateList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (ContractEntityExt contractEntityExt : contractEntityExtList) {
            ContractUpdateDTO contractUpdateDTO = new ContractUpdateDTO();
            contractUpdateDTO.setId(contractEntityExt.getId());
            JSONObject data = new JSONObject();
//            data.put("num_32",0);
            data.put(ContractEnum.BAD_AMOUNT.getAttr(), 0);
            contractUpdateDTO.setData(data);
            contractUpdateDTO.setUpdateTime(contractEntityExt.getUpdateTime());
            contractUpdateList.add(contractUpdateDTO);
        }
        contractUpdateBatchDTO.setContractUpdateList(contractUpdateList);
        contractService.updateBatch(contractUpdateBatchDTO, false,false);
        ContractEntityExt contractEntityExt = contractEntityExtList.get(contractEntityExtList.size()-1);
        if ( Objects.nonNull(contractEntityExt) ) {
            idGte = contractEntityExt.getId();
        }
        return idGte;
    }

    @Override
    public ScriptVO scriptParchaseAndPayPlanExplains(UpdateFundManagemenExpalinstDTO updateFundManagemenExpalinstDTO) throws XbbException {
        Integer businessType = updateFundManagemenExpalinstDTO.getBusinessType();
        ScriptVO scriptVO;
        if ( Objects.equals(businessType, XbbRefTypeEnum.PURCHASE.getCode()) ){
            scriptVO = scriptPurchaseExplains(updateFundManagemenExpalinstDTO);
        } else if (Objects.equals(businessType, XbbRefTypeEnum.PAY_PLAN.getCode())){
            scriptVO = scriptPayPlanExplains(updateFundManagemenExpalinstDTO);
        } else {
            throw new XbbException(TemplateErrorCodeEnum.API_ERROR_350006);
        }
        return scriptVO;
    }

    @Override
    public ScriptVO scriptPurchaseExplains(UpdateFundManagemenExpalinstDTO updateFundManagemenExpalinstDTO) throws XbbException {
        ScriptVO scriptVO = new ScriptVO();
        List<String> corpidList = updateFundManagemenExpalinstDTO.getCorpidList();
//        if ( CollectionsUtil.isEmpty(corpidList) ) {
//            corpidList = paasFormExplainModel.getCorpidList();
//            corpidList.remove("0");
//        }
        Integer businessType = updateFundManagemenExpalinstDTO.getBusinessType();
        List<FundPurchaseScriptEnum> list = FundPurchaseScriptEnum.getAllEnum();

        Class<?> clazz = getBusinessClass(businessType);
        Object[] objs = clazz.getEnumConstants();
        Map<String, FundPurchaseScriptEnum> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for ( FundPurchaseScriptEnum fundPurchaseScriptEnum : list ) {
            for ( Object obj : objs ) {
                try {
                    //需要修改的字段
                    String attr = fundPurchaseScriptEnum.getPurchaseEnum().getAttr();
                    String name = (String) clazz.getMethod("getAttr").invoke(obj);
                    if ( !Objects.equals(name, attr) ) {
                        continue;
                    }
                    params.put(name, fundPurchaseScriptEnum);
                } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                    LOGGER.error("",e);
                }catch (Exception e){
                    LOGGER.error("",e);
                }
            }
        }
        Integer count = 0;
        List<FundPurchaseScriptEnum> updateFundPurchaseScriptEnum = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<FundPurchaseScriptEnum> addFundPurchaseScriptEnum = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Long startTime = DateTimeUtil.getInt();
        try {
            Boolean flag = true;
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            CommentUtil.addToMap(param,"corpidIn",corpidList);
            param.put("del", 0);
            param.put("businessType", businessType);
            param.put("orderByStr", "id asc");
            int j = 1;
            int pageSize = 500;
            param.put("pageSize", pageSize);
            Long idGte = 0L;
            while (flag) {
                LOGGER.info("当前是" + j++ + "页");
                param.put("idGte", idGte);
                List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.list(param);
                if ( paasFormExplainEntityList.isEmpty() ) {
                    flag = false;
                    continue;
                }
                PaasFormExplainEntity paasFormExplain = paasFormExplainEntityList.get(paasFormExplainEntityList.size()-1);
                if ( Objects.nonNull(paasFormExplain) ) {
                    idGte = paasFormExplain.getId();
                }
                LOGGER.info("共有====" + paasFormExplainEntityList.size() + "条数据需要刷");
                List<PaasFormExplainEntity> paasFormExplainEntities = new ArrayList<>(paasFormExplainEntityList.size());
                for ( PaasFormExplainEntity paasFormExplainEntity : paasFormExplainEntityList ) {
                    List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                    Map<String, FieldAttrEntity> oldAttrMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    for ( FieldAttrEntity fieldAttrEntity : fieldAttrEntityList ) {
                        oldAttrMap.put(fieldAttrEntity.getAttr(), fieldAttrEntity);
                    }
                    updateFundPurchaseScriptEnum.clear();
                    addFundPurchaseScriptEnum.clear();
                    for ( FundPurchaseScriptEnum fundPurchaseScriptEnum : list ) {
                        FieldAttrEntity oldFieldAttrEntity = oldAttrMap.get(fundPurchaseScriptEnum.getPurchaseEnum().getAttr());
                        if ( Objects.isNull(oldFieldAttrEntity) ) {
                            addFundPurchaseScriptEnum.add(fundPurchaseScriptEnum);
                        } else {
                            updateFundPurchaseScriptEnum.add(fundPurchaseScriptEnum);
                        }
                    }
                    //更新字段
                    for ( FundPurchaseScriptEnum fundPurchaseScriptEnum : updateFundPurchaseScriptEnum ) {
                        String attr = fundPurchaseScriptEnum.getPurchaseEnum().getAttr();
                        for ( FieldAttrEntity fieldAttrEntity : fieldAttrEntityList ) {
                            if ( Objects.equals(fieldAttrEntity.getAttr(), attr) ) {
                                FundPurchaseScriptEnum updateFundPurchaseScriptAttrEnum = params.get(attr);
                                if ( Objects.nonNull(updateFundPurchaseScriptAttrEnum) ) {
                                    BeanUtil.copyProperties(updateFundPurchaseScriptAttrEnum.getPurchaseEnum(), fieldAttrEntity);
                                    if ( Objects.equals(updateFundPurchaseScriptAttrEnum.getPurchaseEnum(), PurchaseEnum.ADD_PAYPLAN) ) {
                                        fieldAttrEntity.setNumericalLimitsFlag(1);
                                        fieldAttrEntity.setNumericalLimits(new NumericalLimitsPoJo(0D, 50D));
                                    }
                                    if ( Objects.equals(updateFundPurchaseScriptAttrEnum.getPurchaseEnum().getFieldType(), FieldTypeEnum.LINK_FORM_BUTTON.getType()) ) {
                                        if ( Objects.equals(updateFundPurchaseScriptAttrEnum.getPurchaseEnum(), PurchaseEnum.ADD_PAY_SHEET) ) {
                                            FundPurchaseScriptEnum.initAddPaySheet(fieldAttrEntity);
                                        } else if ( Objects.equals(updateFundPurchaseScriptAttrEnum.getPurchaseEnum(), PurchaseEnum.ADD_WRITE_OFF_PREPAY) ) {
                                            FundPurchaseScriptEnum.initAddWriteOffPrepay(fieldAttrEntity);
                                        }
                                    } else if ( Objects.equals(updateFundPurchaseScriptAttrEnum.getPurchaseEnum().getFieldType(), FieldTypeEnum.NUM.getType()) ) {
                                        if ( Objects.equals(updateFundPurchaseScriptAttrEnum.getPurchaseEnum(), PurchaseEnum.FINISH_AMOUNT) ) {
                                            FundPurchaseScriptEnum.initFinishAmount(fieldAttrEntity);
                                        } else if ( Objects.equals(updateFundPurchaseScriptAttrEnum.getPurchaseEnum(), PurchaseEnum.UN_FINISH_AMOUNT) ) {
                                            FundPurchaseScriptEnum.initUnFinishAmount(fieldAttrEntity);
                                        } else if ( Objects.equals(updateFundPurchaseScriptAttrEnum.getPurchaseEnum(), PurchaseEnum.BAD_AMOUNT) ) {
                                            FundPurchaseScriptEnum.initAddBadAmount(fieldAttrEntity);
                                            fieldAttrEntity.setSort(9629);
                                        } else if ( Objects.equals(updateFundPurchaseScriptAttrEnum.getPurchaseEnum(), PurchaseEnum.RECEINE_PERCENT) ) {
                                            FundPurchaseScriptEnum.initReceivePrecent(fieldAttrEntity);
                                        } else if ( Objects.equals(updateFundPurchaseScriptAttrEnum.getPurchaseEnum(), PurchaseEnum.INVOICE_AMOUNT) ) {
                                            FundPurchaseScriptEnum.initInvoiceAmount(fieldAttrEntity);
                                        } else if ( Objects.equals(updateFundPurchaseScriptAttrEnum.getPurchaseEnum(), PurchaseEnum.UN_INVOICE_AMOUNT) ) {
                                            FundPurchaseScriptEnum.initUnInvoiceAmount(fieldAttrEntity);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    List<FieldAttrEntity> newFieldAttrEntityList = fieldAttrEntityList;
                    //新增字段
                    for ( FundPurchaseScriptEnum fundPurchaseScriptEnum : addFundPurchaseScriptEnum ) {
                        PurchaseEnum purchaseEnum = fundPurchaseScriptEnum.getPurchaseEnum();
                        if ( Objects.nonNull(fundPurchaseScriptEnum) ) {
                            FieldAttrEntity addFieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                            BeanUtil.copyProperties(purchaseEnum, addFieldAttrEntity);
                            if ( Objects.equals(purchaseEnum.getFieldType(), FieldTypeEnum.LINK_FORM_BUTTON.getType()) ) {
                                if ( Objects.equals(purchaseEnum, PurchaseEnum.ADD_PAY_SHEET) ) {
                                    FundPurchaseScriptEnum.initAddPaySheet(addFieldAttrEntity);
                                } else if ( Objects.equals(purchaseEnum, PurchaseEnum.ADD_WRITE_OFF_PREPAY) ) {
                                    FundPurchaseScriptEnum.initAddWriteOffPrepay(addFieldAttrEntity);
                                }
                            } else if ( Objects.equals(purchaseEnum.getFieldType(), FieldTypeEnum.NUM.getType()) ) {
                                if ( Objects.equals(purchaseEnum, PurchaseEnum.FINISH_AMOUNT) ) {
                                    FundPurchaseScriptEnum.initFinishAmount(addFieldAttrEntity);
                                } else if ( Objects.equals(purchaseEnum, PurchaseEnum.UN_FINISH_AMOUNT) ) {
                                    FundPurchaseScriptEnum.initUnFinishAmount(addFieldAttrEntity);
                                } else if ( Objects.equals(purchaseEnum, PurchaseEnum.BAD_AMOUNT) ) {
                                    FundPurchaseScriptEnum.initAddBadAmount(addFieldAttrEntity);
                                    addFieldAttrEntity.setSort(9629);
                                } else if ( Objects.equals(purchaseEnum, PurchaseEnum.RECEINE_PERCENT) ) {
                                    FundPurchaseScriptEnum.initReceivePrecent(addFieldAttrEntity);
                                } else if ( Objects.equals(purchaseEnum, PurchaseEnum.INVOICE_AMOUNT) ) {
                                    FundPurchaseScriptEnum.initInvoiceAmount(addFieldAttrEntity);
                                } else if ( Objects.equals(purchaseEnum, PurchaseEnum.UN_INVOICE_AMOUNT) ) {
                                    FundPurchaseScriptEnum.initUnInvoiceAmount(addFieldAttrEntity);
                                }
                            }
                            newFieldAttrEntityList.add(addFieldAttrEntity);
                        }
                    }
                    paasFormExplainEntity.setExplains(JSONObject.toJSONString(newFieldAttrEntityList));
                    paasFormExplainEntities.add(paasFormExplainEntity);
                    count++;
                    LOGGER.info("当前是第" + count + "条数据");
                }
                if ( CollectionsUtil.isNotEmpty(paasFormExplainEntities) ) {
                    paasFormExplainModel.updateBatchExplains(paasFormExplainEntities);
                }
            }
        } catch (Exception e) {
            LOGGER.error("", e);
        }
        String msg = "修改了" + count + "条数据";
        LOGGER.info(msg);
        scriptVO.setMsg(msg);
        LOGGER.info("---更新付款计划模版脚本结束");
        Long endTime = DateTimeUtil.getInt();
        Long consumeTime = endTime - startTime;
        LOGGER.info("---耗时为："+ consumeTime);
        return scriptVO;
    }

    @Override
    public ScriptVO scriptPayPlanExplains(UpdateFundManagemenExpalinstDTO updateFundManagemenExpalinstDTO) throws XbbException {
        ScriptVO scriptVO=new ScriptVO();
        List<String> corpidList = updateFundManagemenExpalinstDTO.getCorpidList();
        List<FundPayPlanScriptEnum> list = FundPayPlanScriptEnum.getAllEnum();
        Integer businessType = updateFundManagemenExpalinstDTO.getBusinessType();
        Class<?> clazz = getBusinessClass(businessType);
        Object[] objs = clazz.getEnumConstants();
        Map<String,FundPayPlanScriptEnum> params=new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for ( FundPayPlanScriptEnum fundPayPlanScriptEnum : list ) {
            for ( Object obj : objs ) {
                try {
                    String attr = fundPayPlanScriptEnum.getPayPlanEnum().getAttr();
                    String name = (String) clazz.getMethod("getAttr").invoke(obj);
                    if ( !Objects.equals(name, attr) ) {
                        continue;
                    }
                    params.put(name,fundPayPlanScriptEnum);
                } catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
                    LOGGER.error("",e);
                } catch (Exception e){
                    LOGGER.error("",e);
                }
            }
        }
        Integer count=0;
        List<FundPayPlanScriptEnum> updateFundPayPlanScriptEnum = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<FundPayPlanScriptEnum> addFundPayPlanScriptEnum = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Long startTime = DateTimeUtil.getInt();
        try {
            Boolean flag = true;
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            CommentUtil.addToMap(param, "corpidIn", corpidList);
            param.put("del", 0);
            param.put("businessType", businessType);
            param.put("orderByStr", "id asc");
            int j = 1;
            int pageSize = 500;
            param.put("pageSize", pageSize);
            Long idGte = 0L;
            while (flag) {
                LOGGER.info("当前是" + j++ + "页");
                param.put("idGte", idGte);
                List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.list(param);
                if ( paasFormExplainEntityList.isEmpty() ) {
                    flag = false;
                    continue;
                }
                PaasFormExplainEntity paasFormExplain = paasFormExplainEntityList.get(paasFormExplainEntityList.size()-1);
                if ( Objects.nonNull(paasFormExplain) ) {
                    idGte = paasFormExplain.getId();
                }
                LOGGER.info("共有====" + paasFormExplainEntityList.size() + "条数据需要刷");
                List<PaasFormExplainEntity> paasFormExplainEntities = new ArrayList<>(paasFormExplainEntityList.size());
                for ( PaasFormExplainEntity paasFormExplainEntity : paasFormExplainEntityList ) {
                    List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(paasFormExplainEntity.getExplains(), FieldAttrEntity.class);
                    Map<String, FieldAttrEntity> oldAttrMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    for ( FieldAttrEntity fieldAttrEntity : fieldAttrEntityList ) {
                        oldAttrMap.put(fieldAttrEntity.getAttr(), fieldAttrEntity);
                    }
                    updateFundPayPlanScriptEnum.clear();
                    addFundPayPlanScriptEnum.clear();
                    for ( FundPayPlanScriptEnum fundPayPlanScriptEnum : list ) {
                        FieldAttrEntity oldFieldAttrEntity = oldAttrMap.get(fundPayPlanScriptEnum.getPayPlanEnum().getAttr());
                        if ( Objects.isNull(oldFieldAttrEntity) ) {
                            addFundPayPlanScriptEnum.add(fundPayPlanScriptEnum);
                        } else {
                            updateFundPayPlanScriptEnum.add(fundPayPlanScriptEnum);
                        }
                    }
                    //更新字段
                    for ( FundPayPlanScriptEnum fundPayPlanScriptEnum : updateFundPayPlanScriptEnum ) {
                        String attr = fundPayPlanScriptEnum.getPayPlanEnum().getAttr();
                        for ( FieldAttrEntity fieldAttrEntity : fieldAttrEntityList ) {
                            if ( Objects.equals(fieldAttrEntity.getAttr(), attr) ) {
                                FundPayPlanScriptEnum updateFundPayPlanScriptAttrEnum = params.get(attr);
                                if ( Objects.nonNull(updateFundPayPlanScriptAttrEnum) ) {
                                    BeanUtil.copyProperties(updateFundPayPlanScriptAttrEnum.getPayPlanEnum(), fieldAttrEntity);
                                    if ( Objects.equals(PayPlanEnum.STATUS, updateFundPayPlanScriptAttrEnum.getPayPlanEnum()) ) {
                                        TempPayPlanEnum.initStatus(fieldAttrEntity);
                                        fieldAttrEntity.setEditable(0);
                                        fieldAttrEntity.setItemBanDefault(BasicConstant.ONE);
                                    } else if ( Objects.equals(PayPlanEnum.ADD_PAYPLAN, updateFundPayPlanScriptAttrEnum.getPayPlanEnum()) ) {
                                        fieldAttrEntity.setNumericalLimitsFlag(1);
                                        fieldAttrEntity.setNumericalLimits(new NumericalLimitsPoJo(0D, 50D));
                                    } else if ( Objects.equals(PayPlanEnum.BAD_AMOUNT, updateFundPayPlanScriptAttrEnum.getPayPlanEnum()) ) {
                                        FundPayPlanScriptEnum.initAddBadAmount(fieldAttrEntity);
                                    } else if ( Objects.equals(PayPlanEnum.INVOICE_AMOUNT, updateFundPayPlanScriptAttrEnum.getPayPlanEnum()) ) {
                                        FundPayPlanScriptEnum.initInvoiceAmount(fieldAttrEntity);
                                    } else if ( Objects.equals(PayPlanEnum.HAS_RED, updateFundPayPlanScriptAttrEnum.getPayPlanEnum()) ) {
                                        FundPayPlanScriptEnum.initHasRed(fieldAttrEntity);
                                    } else if ( Objects.equals(PayPlanEnum.PAY_TYPE, updateFundPayPlanScriptAttrEnum.getPayPlanEnum()) ) {
                                        FundPayPlanScriptEnum.initPayType(fieldAttrEntity);
                                    } else if ( Objects.equals(PayPlanEnum.BELONGER, updateFundPayPlanScriptAttrEnum.getPayPlanEnum()) ) {
                                        fieldAttrEntity.setAttrType(FieldTypeEnum.USER.getAlias());
                                        fieldAttrEntity.setEditHide(1);
                                        fieldAttrEntity.setRequired(0);
                                        fieldAttrEntity.setShowType(ShowTypeEnum.NONE.getCode());
                                        fieldAttrEntity.setScreenType(ScreenTypeEnum.SCREEN_OFF.getType());
                                    } else if ( Objects.equals(PayPlanEnum.PAYMENT_METHOD, updateFundPayPlanScriptAttrEnum.getPayPlanEnum()) ) {
                                        fieldAttrEntity.setAttrType(FieldTypeEnum.COMBO.getAlias());
                                    } else if ( Objects.equals(PayPlanEnum.REAL_AMOUNT, updateFundPayPlanScriptAttrEnum.getPayPlanEnum()) ) {
                                        FundPayPlanScriptEnum.initFinishAmount(fieldAttrEntity);
                                    } else if ( Objects.equals(PayPlanEnum.UN_AMOUNT, updateFundPayPlanScriptAttrEnum.getPayPlanEnum()) ) {
                                        FundPayPlanScriptEnum.initUnAmount(fieldAttrEntity);
                                    }
                                }
                            }
                        }
                    }
                    List<FieldAttrEntity> newFieldAttrEntityList = fieldAttrEntityList;
                    //新增字段
                    for ( FundPayPlanScriptEnum fundPayPlanScriptEnum : addFundPayPlanScriptEnum ) {
                        PayPlanEnum payPlanEnum = fundPayPlanScriptEnum.getPayPlanEnum();
                        if ( Objects.nonNull(payPlanEnum) ) {
                            FieldAttrEntity addFieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                            BeanUtil.copyProperties(payPlanEnum, addFieldAttrEntity);
                            if ( Objects.equals(PayPlanEnum.STATUS, payPlanEnum) ) {
                                TempPayPlanEnum.initStatus(addFieldAttrEntity);
                                addFieldAttrEntity.setEditable(0);
                                addFieldAttrEntity.setItemBanDefault(BasicConstant.ONE);
                            } else if ( Objects.equals(PayPlanEnum.ADD_PAYPLAN, payPlanEnum) ) {
                                addFieldAttrEntity.setNumericalLimitsFlag(1);
                                addFieldAttrEntity.setNumericalLimits(new NumericalLimitsPoJo(0D, 50D));
                            } else if ( Objects.equals(PayPlanEnum.BAD_AMOUNT, payPlanEnum) ) {
                                FundPayPlanScriptEnum.initAddBadAmount(addFieldAttrEntity);
                            } else if ( Objects.equals(PayPlanEnum.INVOICE_AMOUNT, payPlanEnum) ) {
                                FundPayPlanScriptEnum.initInvoiceAmount(addFieldAttrEntity);
                            } else if ( Objects.equals(PayPlanEnum.HAS_RED, payPlanEnum) ) {
                                FundPayPlanScriptEnum.initHasRed(addFieldAttrEntity);
                            } else if ( Objects.equals(PayPlanEnum.PAY_TYPE, payPlanEnum) ) {
                                FundPayPlanScriptEnum.initPayType(addFieldAttrEntity);
                            } else if ( Objects.equals(PayPlanEnum.BELONGER, payPlanEnum) ) {
                                addFieldAttrEntity.setAttrType(FieldTypeEnum.USER.getAlias());
                                addFieldAttrEntity.setEditHide(1);
                                addFieldAttrEntity.setRequired(0);
                                addFieldAttrEntity.setShowType(ShowTypeEnum.NONE.getCode());
                                addFieldAttrEntity.setScreenType(ScreenTypeEnum.SCREEN_OFF.getType());
                            } else if ( Objects.equals(PayPlanEnum.PAYMENT_METHOD, payPlanEnum) ) {
                                addFieldAttrEntity.setAttrType(FieldTypeEnum.COMBO.getAlias());
                            } else if ( Objects.equals(PayPlanEnum.REAL_AMOUNT, payPlanEnum) ) {
                                FundPayPlanScriptEnum.initFinishAmount(addFieldAttrEntity);
                            } else if ( Objects.equals(PayPlanEnum.UN_AMOUNT, payPlanEnum) ) {
                                FundPayPlanScriptEnum.initUnAmount(addFieldAttrEntity);
                            }
                            newFieldAttrEntityList.add(addFieldAttrEntity);
                        }
                    }
                    paasFormExplainEntity.setExplains(JSONObject.toJSONString(newFieldAttrEntityList));
                    paasFormExplainEntities.add(paasFormExplainEntity);
                    count++;
                    LOGGER.info("当前是第" + count + "条数据");
                }
                if ( CollectionsUtil.isNotEmpty(paasFormExplainEntities) ) {
                    try {
                        paasFormExplainModel.updateBatchExplains(paasFormExplainEntities);
                    } catch ( Exception e) {
                        LOGGER.error("更新数据库时报错，错误信息为：", JSONArray.parseObject(paasFormExplainEntities.toString()));
                    }
                }
            }
        } catch (Exception e) {
            LOGGER.error("", e);
        }
        String msg = "修改了" + count + "条数据";
        scriptVO.setMsg(msg);
        LOGGER.info("---更新付款计划模版脚本结束");
        Long endTime = DateTimeUtil.getInt();
        Long consumeTime = endTime - startTime;
        LOGGER.info("---耗时为："+ consumeTime);
        return scriptVO;
    }

    /**
     * 更新分组
     *
     * @param updateTabDTO
     * @return
     * @throws XbbException
     */
    @Override
    public ScriptVO scriptPayPlanTab(UpdateTabDTO updateTabDTO) throws XbbException {
        Integer businessType = updateTabDTO.getBusinessType();
        List<String> corpidList = updateTabDTO.getCorpidList();
        if ( CollectionsUtil.isEmpty(corpidList) ){
            corpidList = paasFormExplainModel.getCorpidList();
        }
        LOGGER.info("共有"+corpidList.size()+"家公司需要刷");
        int i=1;
        Long startTime = DateTimeUtil.getInt();
        for ( String corpid : corpidList ) {
            int j = corpidList.size() -i;
            LOGGER.info("当前是第"+i+"家公司需要刷,还有"+j+"家公司需要刷");
            PaasFormEntityExt paasFormEntityExt = paasFormModel.getByBusinessType(XbbRefTypeEnum.PAY_PLAN.getCode(),corpid);
            if ( Objects.nonNull(paasFormEntityExt) ){
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put("corpid",corpid);
                param.put("del",0);
                param.put("formId",paasFormEntityExt.getId());
                param.put("groupByStr", "creator_id");
                List<PaasListGroupEntity> list = paasListGroupModel.list(param);
                List<PaasListGroupEntity> paasListGroupList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                for ( PaasListGroupEntity item:list ) {
                    PaasListGroupEntity paasListGroupEntity = new PaasListGroupEntity();
                    paasListGroupEntity.setCorpid(corpid);
                    paasListGroupEntity.setAppId(item.getAppId());
                    paasListGroupEntity.setMenuId(item.getMenuId());
                    paasListGroupEntity.setName(ListGroupEnum.PAY_BAD_DEBT.getName());
                    paasListGroupEntity.setSort(8);
                    paasListGroupEntity.setJsonData("");
                    paasListGroupEntity.setCreatorId(item.getCreatorId());
                    paasListGroupEntity.setAddTime(item.getAddTime());
                    paasListGroupEntity.setUpdateTime(item.getUpdateTime());
                    paasListGroupEntity.setDefaultGroupCode(ListGroupEnum.PAY_BAD_DEBT.getCode());
                    paasListGroupEntity.setFormId(paasFormEntityExt.getId());
                    paasListGroupList.add(paasListGroupEntity);
                }
                if ( CollectionsUtil.isNotEmpty(paasListGroupList) ) {
                    paasListGroupModel.insertBatch(paasListGroupList);
                }
                i++;
            }
        }
        LOGGER.info("---更新采购合同流程表单解释脚本结束");
        Long endTime = DateTimeUtil.getInt();
        Long consumeTime = endTime - startTime;
        LOGGER.info("---耗时为："+ consumeTime);
        return null;
    }

    /**
     * 更新付款计划tab栏
     *
     * @param updateTabDTO
     * @return
     * @throws XbbException
     */
    @Override
    public ScriptVO scriptPayPlanDetail(UpdateTabDTO updateTabDTO) throws XbbException {
        List<String> corpidList = updateTabDTO.getCorpidList();
        List<Integer> businessTypeList = updateTabDTO.getBusinessTypeList();
        if ( CollectionsUtil.isEmpty(corpidList) ){
            corpidList = companyModel.getCorpidList();
        }
        LOGGER.info("共有"+corpidList.size()+"家公司需要刷");
        int i=1;
        Long startTime = DateTimeUtil.getInt();
        for (Integer businessType :  businessTypeList) {
            BusinessDetailTabEnum businessDetailTabEnum ;
            TabConfigPojo tabConfigPojo = new TabConfigPojo();
            if ( Objects.equals(businessType, XbbRefTypeEnum.PAY_PLAN.getCode()) ) {
                businessDetailTabEnum = BusinessDetailTabEnum.PAY_PLAN_INVOICE_HISTORY;
            } else if ( Objects.equals(businessType, XbbRefTypeEnum.SUPPLIER.getCode()) ) {
                businessDetailTabEnum = BusinessDetailTabEnum.SUPPLIER_INVOICE_HISTORY;
            } else if ( Objects.equals(businessType, XbbRefTypeEnum.PURCHASE.getCode()) ) {
                businessDetailTabEnum = BusinessDetailTabEnum.PURCHASE_INVOICE_HISTORY;
            } else {
                throw new XbbException(TemplateErrorCodeEnum.API_ERROR_350006);
            }
            BeanUtil.copyProperties(businessDetailTabEnum.getAnEnum(), tabConfigPojo);
            tabConfigPojo.setAttr(businessDetailTabEnum.getAnEnum().getKey());
            tabConfigPojo.setEnable(BasicConstant.IS_USE);
            tabConfigPojo.setSpecialMemo(businessDetailTabEnum.getSpecialMemo());
            for ( String corpid : corpidList ) {
                LOGGER.info("共"+corpidList.size() +"家公司，当前是第" + i + "家公司");
                Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                params.put("corpid", corpid);
                params.put("businessType", businessType);
                params.put("del", 0);
                List<DetailTabConfigEntity> detailTabConfigEntityList = detailTabConfigModel.findEntitys(params);
                List<DetailTabConfigEntity> needUpdateList = new ArrayList<>(detailTabConfigEntityList.size());
                if ( Objects.equals(updateTabDTO.getOperate(),0) ) {
                    for ( DetailTabConfigEntity item : detailTabConfigEntityList ) {
                        List<TabConfigPojo> tabConfigList = JSONArray.parseArray(item.getTabConfig(), TabConfigPojo.class);
                        Boolean noRepeat = false;//没有重复
                        for ( TabConfigPojo configPojo : tabConfigList ) {
                            if ( Objects.equals(configPojo.getAttr(), businessDetailTabEnum.getAnEnum().getKey()) ) {
                                noRepeat = true;//重复了
                            }
                        }
                        if ( !noRepeat ) {
                            tabConfigPojo.setSort(tabConfigList.size() + 1);
                            tabConfigList.add(tabConfigPojo);
                            item.setTabConfig(JSONObject.toJSONString(tabConfigList));
                            needUpdateList.add(item);
                        }
                    }
                } else if ( Objects.equals(updateTabDTO.getOperate(),1) ){
                    for ( DetailTabConfigEntity item : detailTabConfigEntityList ) {
                        List<TabConfigPojo> tabConfigList = JSONArray.parseArray(item.getTabConfig(), TabConfigPojo.class);
                        Boolean noRepeat = false;//没有重复
                        TabConfigPojo repeatConfig = new TabConfigPojo();
                        for ( TabConfigPojo configPojo : tabConfigList ) {
                            if ( Objects.equals(configPojo.getAttr(), businessDetailTabEnum.getAnEnum().getKey()) ) {
                                noRepeat = true;//重复了
                                repeatConfig = configPojo;
                                break;
                            }
                        }
                        if ( noRepeat ) {
                            tabConfigList.remove(repeatConfig);
                            item.setTabConfig(JSONObject.toJSONString(tabConfigList));
                            needUpdateList.add(item);
                        }
                    }
                }
                if ( CollectionsUtil.isNotEmpty(needUpdateList) ) {
                    detailTabConfigModel.updateBatch(needUpdateList);
                }
                i++;
            }
        }

        LOGGER.info("---更新付款计划tab栏脚本结束");
        Long endTime = DateTimeUtil.getInt();
        Long consumeTime = endTime - startTime;
        LOGGER.info("---耗时为："+ consumeTime);
        return null;
    }

    @Override
    public ScriptVO repairDepartmentId(RepairDepartmentIdBecauseApiDTO repairDepartmentIdBecauseApiDTO) throws XbbException {

        String corpid = repairDepartmentIdBecauseApiDTO.getCorpid();
        Long startTime = repairDepartmentIdBecauseApiDTO.getStartTime();
        Long endTime = repairDepartmentIdBecauseApiDTO.getEndTime();

        Integer page = 0;
        Integer pageSize = 100;
        Boolean stopFlag = false;

        OperateLogListDTO operateLogListDTO = new OperateLogListDTO();
        operateLogListDTO.setCorpid(corpid);
        operateLogListDTO.setPlatform(PlatFormEnum.WEB.getValue());
        operateLogListDTO.setMemoLike("API接口”编辑");
        operateLogListDTO.setModuleType(OperateModuleTypeEnum.CONTRACT.getCode());
        operateLogListDTO.setOpType(OperateTypeEnum.EDIT.getCode());
        operateLogListDTO.setOperateMaxTime(endTime);
        operateLogListDTO.setOperateMinTime(startTime);
        operateLogListDTO.setPageSize(pageSize);

        Integer count = 0;
        while (!stopFlag) {
            page ++;


            operateLogListDTO.setPage(page);
            OperateLogListVO operateLogListVO = operateLogService.list(operateLogListDTO);
            List<OperateLogVO> operateLogs = operateLogListVO.getList();

            if (operateLogs.size() < pageSize) {
                stopFlag = true;
            }

            for (OperateLogVO operateLog : operateLogs) {
                count ++;
                LOGGER.info("now count:" + count);

                Long contractId = StringUtil.StringToLong(operateLog.getOpObjectId(), null);
                if (Objects.isNull(contractId)) {
                    LOGGER.info("contractId is null，operateLogId：" + operateLog.getId());
                    continue;
                }
                ContractEntityExt contract = contractModel.getByKey(contractId, corpid);
                //合同不存在，跳过
                if (Objects.isNull(contract)) {
                    LOGGER.info("contract not exist，contractId：" + contractId);
                    continue;
                }
                Long departmentId = contract.getDepartmentId();

                //当合同存在所属部门时，不再设置
                if (Objects.nonNull(departmentId) && departmentId > 0L) {
                    LOGGER.info("contract has departmentId，contractId：" + contractId);
                    continue;
                }

                OperateDetailLogDTO operateDetailLogDTO = new OperateDetailLogDTO();
                operateDetailLogDTO.setCorpid(corpid);
                operateDetailLogDTO.setPlatform(PlatFormEnum.WEB.getValue());
                operateDetailLogDTO.setModuleType(OperateModuleTypeEnum.CONTRACT.getCode());
                operateDetailLogDTO.setOpType(OperateTypeEnum.EDIT.getCode());
                operateDetailLogDTO.setOperateLogId(operateLog.getId());

                OperateDetailLogVO operateDetailLogVO = operateLogService.detail(operateDetailLogDTO);
                departmentId = getDepartmentId(corpid, operateDetailLogVO);

                if (Objects.isNull(departmentId)) {
                    continue;
                }

                contract.setDepartmentId(departmentId);
                contractModel.update(contract);
            }
        }

        return new ScriptVO();
    }

    @Override
    public ScriptVO repairAddExplainProduct(AllScriptDTO allScriptDTO) throws XbbException {
        long start = DateTimeUtil.getInt();
        LocaleContextHolder.setLocale(Locale.CHINA);
        List<String> corpidList = allScriptDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = companyModel.getCorpidList();
        }
        allScriptDTO.setCorpidList(corpidList);

        List<Integer> businessTypeList = Arrays.asList(XbbRefTypeEnum.TRANSFER.getCode(),XbbRefTypeEnum.REFUND.getCode(),XbbRefTypeEnum.RETURNED_PURCHASE.getCode(), XbbRefTypeEnum.INVENTORY.getCode(),XbbRefTypeEnum.REFUND_INSTOCK.getCode());
        allScriptDTO.setOperate(RepairExplainEnum.ADD.getCode());
        for (Integer businessType : businessTypeList) {
            if (Objects.equals(businessType, XbbRefTypeEnum.TRANSFER.getCode())) {
                allScriptDTO.setAttr(TransferEnum.PRODUCTS.getAttr());
                allScriptDTO.setAfterAttr(TransferProductEnum.NUM.getAttr());
                allScriptDTO.setBusinessType(XbbRefTypeEnum.TRANSFER.getCode());
            }else if (Objects.equals(businessType, XbbRefTypeEnum.REFUND.getCode())){
                allScriptDTO.setAttr(RefundEnum.PRODUCTS.getAttr());
                allScriptDTO.setAfterAttr(RefundProductEnum.SOURCE_DOC.getAttr());
                allScriptDTO.setBusinessType(XbbRefTypeEnum.REFUND.getCode());
            }else if (Objects.equals(businessType, XbbRefTypeEnum.RETURNED_PURCHASE.getCode())){
                allScriptDTO.setAttr(ReturnedPurchaseEnum.PRODUCTS.getAttr());
                allScriptDTO.setAfterAttr(ReturnPurchaseProductEnum.SOURCE_DOC.getAttr());
                allScriptDTO.setBusinessType(XbbRefTypeEnum.RETURNED_PURCHASE.getCode());
            }else if (Objects.equals(businessType, XbbRefTypeEnum.INVENTORY.getCode())){
                allScriptDTO.setAttr(InventoryEnum.PRODUCT.getAttr());
                allScriptDTO.setAfterAttr(InventoryProductEnum.MEMO.getAttr());
                allScriptDTO.setBusinessType(XbbRefTypeEnum.INVENTORY.getCode());
            }else if (Objects.equals(businessType, XbbRefTypeEnum.REFUND_INSTOCK.getCode())){
                allScriptDTO.setAttr(RefundInstockEnum.PRODUCT.getAttr());
                allScriptDTO.setAfterAttr(RefundInstockProductEnum.NUM.getAttr());
                allScriptDTO.setBusinessType(XbbRefTypeEnum.REFUND_INSTOCK.getCode());
            }
            Class<?> clazz = getBusinessProductClass(businessType);
            Class<?> tempClazz = getBusinessProductTempClass(businessType);
            Class<?> parentClazz = getBusinessClass(businessType);
            Class<?> tempParentClazz = getBusinessTempClass(businessType);
            List<FieldAttrEntity> fieldAttrEntities = productPre(businessType, allScriptDTO.getAttr(), clazz, tempClazz);
            FieldAttrEntity expireDateEntitity = expireProductPre(businessType, allScriptDTO.getAttr(), clazz, tempClazz);
            List<FieldAttrEntity> parentAttrEntities = parentPre(businessType, allScriptDTO.getAttr(), parentClazz, tempParentClazz);
            RepairExplainEnum repairExplainEnum = RepairExplainEnum.getByCode(allScriptDTO.getOperate());

            switch (repairExplainEnum){
                case ADD:
                    addImproveExplainProduct(allScriptDTO, fieldAttrEntities, parentAttrEntities, expireDateEntitity);
                    break;
//                case DEL:
//                    delWorkOrderExplainProduct(allScriptDTO, clazz, tempClazz, allScriptDTO.getAttr());
                default:
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001,"未知操作");
            }
        }

        LOGGER.warn("consume:" + (DateTimeUtil.getInt() - start));
        return null;
    }

    private FieldAttrEntity expireProductPre(Integer businessType, String attr, Class<?> clazz, Class<?> tempClazz) {
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        List<String> enumAttrs = InitExplainsHelper.getBusinessEnumAttrs(clazz);
        List objs = new ArrayList();
        switch (xbbRefTypeEnum){
            case TRANSFER:
                objs = Arrays.asList(TransferProductEnum.EXPIRE_DATE);
                break;
            case REFUND_INSTOCK:
                objs = Arrays.asList(RefundInstockProductEnum.EXPIRE_DATE);
                break;
            case INVENTORY:
                objs = Arrays.asList(InventoryProductEnum.EXPIRE_DATE);
                break;
            default:
                break;
        }
        FieldAttrEntity newFieldAttrEntity = null;
        for (Object obj : objs) {
            newFieldAttrEntity = InitExplainsHelper.setField(clazz, enumAttrs, obj);
            try {
                Method method = tempClazz.getMethod("init" + newFieldAttrEntity.getSaasAttr().substring(0, 1).toUpperCase() + newFieldAttrEntity.getSaasAttr().substring(1), FieldAttrEntity.class);
                method.invoke(tempClazz, newFieldAttrEntity);

            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
            newFieldAttrEntity.setIsRedundant(0);
            newFieldAttrEntity.setIsForbidden(0);
            newFieldAttrEntity.setVisible(1);
            newFieldAttrEntity.setParentAttr(attr);
        }
        return newFieldAttrEntity;
    }

    private void delWorkOrderExplainProduct(AllScriptDTO allScriptDTO, Class<?> clazz, Class<?> tempClazz, String attr) throws XbbException {

        Integer businessType = allScriptDTO.getBusinessType();
        LOGGER.warn(allScriptDTO.getCorpidList().size() + "家公司");
        Integer index = 1;
        List<Long> failList = new ArrayList<>();
        for (String corpid : allScriptDTO.getCorpidList()) {
            LOGGER.warn(index + "/" + allScriptDTO.getCorpidList().size());
            index++;
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("del", 0);
            param.put("businessType", businessType);
            if (allScriptDTO.getFormId() != null) {
                param.put("formId", allScriptDTO.getFormId());
            }
            if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
                List<WorkOrderExplainEntity> entitys = workOrderExplainModel.findEntitys(param);

                for (WorkOrderExplainEntity entity : entitys) {
                    boolean canDelete = true;
                    List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(entity.getExplains(),FieldAttrEntity.class);
                    for (int i = 0; i < fieldAttrEntityList.size(); i++) {
                        //插入到当前字段后面
                        FieldAttrEntity fieldAttrEntity = fieldAttrEntityList.get(i);

                        if (Objects.equals(FieldTypeEnum.SELECT_PRODUCT.getType(), fieldAttrEntity.getFieldType())) {

                            if (Objects.isNull(fieldAttrEntity.getSubForm()) || Objects.isNull(fieldAttrEntity.getSubForm().getItems())) {
                                LOGGER.warn("关联产品没有subForm的corpid:" + entity.getCorpid() + "/解释id:" + entity.getId() + "/formId:" + entity.getFormId());
                                continue;
                            }
                            List<FieldAttrEntity> subExplainList = (List<FieldAttrEntity>)fieldAttrEntity.getSubForm().getItems();

                            if (canDelete) {
                                Iterator<FieldAttrEntity> iterator = subExplainList.iterator();
                                while (iterator.hasNext()){
                                    FieldAttrEntity next = iterator.next();
                                    if (Objects.equals(next.getAttr(), attr)) {
                                        iterator.remove();
                                        break;
                                    }
                                }
                                fieldAttrEntity.getSubForm().setItems(subExplainList);
                                entity.setExplains(JSONObject.toJSONString(fieldAttrEntityList));
                            }
                            break;
                        }
                    }
                    if (canDelete) {
                        workOrderExplainModel.update(entity);
                    }
                }

            }

        }
        if (failList.isEmpty()) {
            throw new XbbException(ErrorCodeEnum.API_SUCCESS, "更新成功");
        } else {
            throw new XbbException(ErrorCodeEnum.API_SUCCESS, "部分更新成功，id " + failList + "更新失败");
        }


    }

    private List<FieldAttrEntity> parentPre(Integer businessType, String attr, Class<?> parentClazz, Class<?> tempParentClazz) {
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        List<FieldAttrEntity> subFieldAttrList = new ArrayList<>();
        List<String> enumAttrs = InitExplainsHelper.getBusinessEnumAttrs(parentClazz);
        List objs = new ArrayList();
        switch (xbbRefTypeEnum){
            case CONTRACT:
                objs = Arrays.asList(ContractEnum.SHIP_STATUS);
                break;
            case PURCHASE:
                objs = Arrays.asList(PurchaseEnum.RECEIVE_STATUS);
                break;
            case REFUND:
                objs = Arrays.asList(RefundEnum.REFUND_STATUS);
                break;
            case RETURNED_PURCHASE:
                objs = Arrays.asList(ReturnedPurchaseEnum.RETURNED_STATUS);
                break;
            case TRANSFER:
                objs = Arrays.asList(TransferEnum.TRANSFER_STATUS, TransferEnum.TRANSFER_TYPE);
                break;
            case INVENTORY:
                objs = Arrays.asList(InventoryEnum.INVENTORY_STATUS, InventoryEnum.INVENTORY_TYPE);
                break;
            default:
                break;
        }
        for (Object obj : objs) {
            FieldAttrEntity newFieldAttrEntity = InitExplainsHelper.setField(parentClazz, enumAttrs, obj);
            try {
                Method method = tempParentClazz.getMethod("init" + newFieldAttrEntity.getSaasAttr().substring(0, 1).toUpperCase() + newFieldAttrEntity.getSaasAttr().substring(1), FieldAttrEntity.class);
                method.invoke(tempParentClazz, newFieldAttrEntity);

            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
            if (Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.PURCHASE.getCode())) {
                newFieldAttrEntity.setVisible(1);
                newFieldAttrEntity.setIsOpen(0);
            }
            newFieldAttrEntity.setIsRedundant(0);
            subFieldAttrList.add(newFieldAttrEntity);
        }
        return subFieldAttrList;
    }


    private List<FieldAttrEntity> productPre(Integer businessType, String attr, Class clazz, Class tempClazz){
        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(businessType);
        List<FieldAttrEntity> subFieldAttrList = new ArrayList<>();
        List<String> enumAttrs = InitExplainsHelper.getBusinessEnumAttrs(clazz);
        List objs = new ArrayList();
        switch (xbbRefTypeEnum){
            case CONTRACT:
                objs = Arrays.asList(ContractProductEnum.OUTSTOCK_NUM, ContractProductEnum.WAIT_OUTSTOCK_NUM, ContractProductEnum.RETURN_NUM);
                break;
            case PURCHASE:
                objs = Arrays.asList(PurchaseProductEnum.INSTOCK_NUM, PurchaseProductEnum.WAIT_INSTOCK_NUM, PurchaseProductEnum.RETURN_NUM, PurchaseProductEnum.RECEIVE_STATUS);
                break;
            case REFUND:
                objs = Arrays.asList(RefundProductEnum.INSTOCK_NUM, RefundProductEnum.WAIT_INSTOCK_NUM, RefundProductEnum.BATCH, RefundProductEnum.PRODUCE_DATE, RefundProductEnum.GUARANTEE_PERIOD,RefundProductEnum.EXPIRE_DATE, RefundProductEnum.REFUND_STATUS);
                break;
            case RETURNED_PURCHASE:
                objs = Arrays.asList(ReturnPurchaseProductEnum.OUTSTOCK_NUM, ReturnPurchaseProductEnum.WAIT_OUTSTOCK_NUM, ReturnPurchaseProductEnum.BATCH, ReturnPurchaseProductEnum.PRODUCE_DATE, ReturnPurchaseProductEnum.GUARANTEE_PERIOD,ReturnPurchaseProductEnum.EXPIRE_DATE, ReturnPurchaseProductEnum.WAREHOUSE, ReturnPurchaseProductEnum.RETURN_STATUS);
                break;
            case WORK_ORDER:
                objs = Arrays.asList(WorkOrderProductEnum.OUTSTOCK_NUM, WorkOrderProductEnum.WAIT_OUTSTOCK_NUM);
                break;
            case PRODUCTION_ORDER:
                objs = Arrays.asList(ProductionOrderMaterielProductEnum.OUTSTOCK_NUM, ProductionOrderMaterielProductEnum.WAIT_OUTSTOCK_NUM);
                break;
            case TRANSFER:
                objs = Arrays.asList(TransferProductEnum.OUTSTOCK_NUM, TransferProductEnum.INSTOCK_NUM, TransferProductEnum.WAIT_INSTOCK_NUM, TransferProductEnum.TRANSFER_STATUS);
                break;
            case REFUND_INSTOCK:
                objs = Arrays.asList(RefundInstockProductEnum.PRICE, RefundInstockProductEnum.SUBTOTAL);
                break;
            default:
                break;
        }

        for (Object obj : objs) {
            FieldAttrEntity newFieldAttrEntity = InitExplainsHelper.setField(clazz, enumAttrs, obj);
            try {
                 Method method = tempClazz.getMethod("init" + newFieldAttrEntity.getSaasAttr().substring(0, 1).toUpperCase() + newFieldAttrEntity.getSaasAttr().substring(1), FieldAttrEntity.class);
                 method.invoke(tempClazz, newFieldAttrEntity);

            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
            newFieldAttrEntity.setIsRedundant(0);
            newFieldAttrEntity.setIsForbidden(0);
            newFieldAttrEntity.setVisible(1);
            newFieldAttrEntity.setParentAttr(attr);
            subFieldAttrList.add(newFieldAttrEntity);
        }
        return subFieldAttrList;
    }


    /**
     * 通过日志详情，获取部门id
     * @param corpid 公司id
     * @param operateDetailLogVO 操作日志详情
     * @return
     * 创建时间 2020/3/21 10:55 AM
     * 修改时间 2020/3/21 10:55 AM
     * @author chy
     */
    private Long getDepartmentId(String corpid, OperateDetailLogVO operateDetailLogVO) {
        List<DetailLogDataPojo> logList = operateDetailLogVO.getLogList();
        if (Objects.isNull(logList) || logList.isEmpty()) {
            return null;
        }

        for (DetailLogDataPojo detailLogDataPojo : logList) {
            JSONArray datas = detailLogDataPojo.getData();
            for (Object object : datas) {
                JSONObject json = (JSONObject)object;
                String attr = json.getString("attr");
                if (Objects.equals(attr, FieldTypeEnum.DEPARTMENTID.getAlias())) {
                    //更新前的部门名
                    String updataBefore = json.getString("updataBefore");
                    //更新后的部门名
                    String updataAfter = json.getString("updataAfter");
                    //部门从有变更到无
                    if (!StringUtil.isEmpty(updataBefore) && StringUtil.isEmpty(updataAfter)) {
                        Map<String, Object> param = new HashMap<>();
                        param.put("name", updataBefore);
                        param.put("corpid", corpid);
                        List<DepartmentEntity> depList = departmentModel.findEntitys(param);
                        if (depList.isEmpty()) {
                            LOGGER.info("department not exist，updataBefore：" + updataBefore);
                            return null;
                        }
                        return depList.get(0).getId();
                    }
                }
            }
        }
        return null;
    }

    @Override
    public ScriptVO scriptContractLinkBusinessSingleData(RepairContractDataDTO repairContractDataDTO) throws XbbException {
        ScriptVO scriptVO = new ScriptVO();
        List<String> corpidList = repairContractDataDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = companyModel.getCorpidList();
        }
        LOGGER.info("共有" + corpidList.size() + "家数据");
        int i = 0;
        for (String corpid : corpidList) {
            i++;
            LOGGER.info("现在是第" + i + "家公司");
            int pageSize = 1000;
            Long idGte = 0L;
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.CORPID, corpid);
            param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            boolean flag = true;
            int j = 0;
            while (flag) {
                LOGGER.info("当前是" + j++ + "页");
                param.put("pageSize", pageSize);
                param.put("orderByStr", "id asc");
                param.put("idGte", idGte);
                List<ContractEntityExt> contractEntityExtList = contractModel.findEntitys(param);
                if (contractEntityExtList.isEmpty()) {
                    flag = false;
                    continue;
                }
                idGte = updateContractLinkBusinessSingleData(contractEntityExtList, corpid);
            }
        }
        scriptVO.setMsg("总共更新" + i + "家合同数据");
        return scriptVO;
    }

    private Long updateContractLinkBusinessSingleData(List<ContractEntityExt> contractEntityExtList, String corpid) throws XbbException {
        Long idGte = 0L;
        ContractUpdateBatchDTO contractUpdateBatchDTO = new ContractUpdateBatchDTO();
        contractUpdateBatchDTO.setCorpid(corpid);
        List<ContractUpdateDTO> contractUpdateList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (ContractEntityExt contractEntityExt : contractEntityExtList) {
            JSONObject contractData = contractEntityExt.getData();
            boolean linkContactError = Objects.equals(contractData.getString(ContractEnum.LINK_CONTACT.getAttr()), "[]");
            boolean linkOpportunityError = Objects.equals(contractData.getString(ContractEnum.LINK_OPPORTUNITY.getAttr()), "[]");
            boolean linkPartnerError = Objects.equals(contractData.getString(ContractEnum.LINK_PARTNER_CUSTOMER.getAttr()), "[]");
            boolean linkQuotationError = Objects.equals(contractData.getString(ContractEnum.QUOTATION_ID.getAttr()), "[]");
            boolean isLinkBusinessSingleDataError =  linkContactError || linkOpportunityError || linkPartnerError || linkQuotationError;
            if (isLinkBusinessSingleDataError) {
                ContractUpdateDTO contractUpdateDTO = new ContractUpdateDTO();
                contractUpdateDTO.setId(contractEntityExt.getId());
                JSONObject data = new JSONObject();
                if (linkContactError) {
                    data.put(ContractEnum.LINK_CONTACT.getAttr(), null);
                }
                if (linkOpportunityError) {
                    data.put(ContractEnum.LINK_OPPORTUNITY.getAttr(), null);
                }
                if (linkPartnerError) {
                    data.put(ContractEnum.LINK_PARTNER_CUSTOMER.getAttr(), null);
                }
                if (linkQuotationError) {
                    data.put(ContractEnum.QUOTATION_ID.getAttr(), null);
                }
                contractUpdateDTO.setData(data);
                contractUpdateDTO.setUpdateTime(contractEntityExt.getUpdateTime());
                contractUpdateList.add(contractUpdateDTO);
            }
        }
        contractUpdateBatchDTO.setContractUpdateList(contractUpdateList);
        contractService.updateBatch(contractUpdateBatchDTO, false,false);
        ContractEntityExt contractEntityExt = contractEntityExtList.get(contractEntityExtList.size() - 1);
        if ( Objects.nonNull(contractEntityExt) ) {
            idGte = contractEntityExt.getId();
        }
        return idGte;
    }

    private void addImproveExplainProduct(AllScriptDTO allScriptDTO, List<FieldAttrEntity> fieldAttrEntities, List<FieldAttrEntity> parentAttrEntities, FieldAttrEntity expireDateEntity) throws XbbException{

        HashSet<String> attrList = new HashSet<>();
        HashSet<String> parentAttrList = new HashSet<>();
        for (FieldAttrEntity fieldAttrEntity : fieldAttrEntities) {
            attrList.add(fieldAttrEntity.getAttr());
        }
        if (Objects.nonNull(expireDateEntity)) {
            attrList.add(expireDateEntity.getAttr());
        }
        for (FieldAttrEntity parentAttrEntity : parentAttrEntities) {
            parentAttrList.add(parentAttrEntity.getAttr());
        }
        String afterAttr = allScriptDTO.getAfterAttr();
        Integer businessType = allScriptDTO.getBusinessType();
        boolean insertParentFieldAttr = !parentAttrEntities.isEmpty();
        boolean needExpire = Objects.nonNull(expireDateEntity);
        LOGGER.warn(allScriptDTO.getCorpidList().size() + "家公司");
        Integer index = 1;
        List<Long> failList = new ArrayList<>();
        List<String> corpidList = allScriptDTO.getCorpidList();
        List<String> hasBatchConfigCompany = new ArrayList<>();
        if (Objects.equals(businessType, XbbRefTypeEnum.TRANSFER.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.REFUND_INSTOCK.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.INVENTORY.getCode())
        || Objects.equals(businessType, XbbRefTypeEnum.REFUND.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.RETURNED_PURCHASE.getCode())) {
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            param.put("configAlias", CompanyConfigEnum.ENABLE_BATCH_SHELF_MANAGEMENT.getAlias());
            param.put("corpidList", corpidList);
            param.put("noLimit", 1);
            param.put("columns", "corpid");
            param.put("configValue", "1");
            List<CompanyConfigEntity> batchConfigList = companyConfigModel.findEntitys(param);
            batchConfigList.forEach(config -> {
                hasBatchConfigCompany.add(config.getCorpid());
            });
        }
        for (String corpid : corpidList) {
            LOGGER.warn(index + "/" + allScriptDTO.getCorpidList().size());
            index++;
            boolean batchShelf = hasBatchConfigCompany.contains(corpid);

            if (Objects.equals(businessType, XbbRefTypeEnum.REFUND.getCode()) || Objects.equals(businessType, XbbRefTypeEnum.RETURNED_PURCHASE.getCode())) {
                if (batchShelf) {
                    for (FieldAttrEntity fieldAttrEntity : fieldAttrEntities) {
                        if (Objects.equals(fieldAttrEntity.getAttr(), SelectProductEnum.PRODUCE_DATE.getAttr())
                        || Objects.equals(fieldAttrEntity.getAttr(), SelectProductEnum.BATCH.getAttr())
                        || Objects.equals(fieldAttrEntity.getAttr(), SelectProductEnum.GUARANTEE_PERIOD.getAttr())
                        || Objects.equals(fieldAttrEntity.getAttr(), SelectProductEnum.EXPIRE_DATE.getAttr())) {
                            fieldAttrEntity.setVisible(1);
                            fieldAttrEntity.setEditHide(0);
                        }
                    }
                }else {
                    for (FieldAttrEntity fieldAttrEntity : fieldAttrEntities) {
                        if (Objects.equals(fieldAttrEntity.getAttr(), SelectProductEnum.PRODUCE_DATE.getAttr())
                                || Objects.equals(fieldAttrEntity.getAttr(), SelectProductEnum.BATCH.getAttr())
                                || Objects.equals(fieldAttrEntity.getAttr(), SelectProductEnum.GUARANTEE_PERIOD.getAttr())
                                || Objects.equals(fieldAttrEntity.getAttr(), SelectProductEnum.EXPIRE_DATE.getAttr())) {
                            fieldAttrEntity.setVisible(0);
                            fieldAttrEntity.setEditHide(1);
                        }
                    }
                }
            }

            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("del", 0);
            param.put("businessType", businessType);
            if (allScriptDTO.getFormId() != null) {
                param.put("formId", allScriptDTO.getFormId());
            }
            if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {
                List<WorkOrderExplainEntity> entitys = workOrderExplainModel.getNoHandleExplainsByFindEntitys(param);
                for (WorkOrderExplainEntity entity : entitys) {
                    if (Objects.equals("[]", entity.getExplains())) {
                        continue;
                    }
                    boolean canInsert = true;
                    List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(entity.getExplains(),FieldAttrEntity.class);
                    for (int i = 0; i < fieldAttrEntityList.size(); i++) {
                        //插入到当前字段后面
                        FieldAttrEntity fieldAttrEntity = fieldAttrEntityList.get(i);

                        if (Objects.equals(FieldTypeEnum.SELECT_PRODUCT.getType(), fieldAttrEntity.getFieldType())) {
                            if (Objects.isNull(fieldAttrEntity.getSubForm()) || Objects.isNull(fieldAttrEntity.getSubForm().getItems())) {
                                failList.add(entity.getId());
                                LOGGER.error(businessType + "业务类型关联产品没有subForm的corpid:" + entity.getCorpid() + "/解释id:" + entity.getId() + "/formId:" + entity.getFormId());
                                continue;
                            }
                            List<FieldAttrEntity> subExplainList = (List<FieldAttrEntity>)fieldAttrEntity.getSubForm().getItems();
                            for (int k = 0;k < subExplainList.size(); k++) {
                                FieldAttrEntity attrEntity1 = subExplainList.get(k);
                                if (attrList.contains(attrEntity1.getAttr())) {
                                    LOGGER.error(businessType + "业务类型" + corpid + "该公司已存在" + attrEntity1.getAttr() + "字段");
                                    failList.add(entity.getId());
                                    canInsert = false;
                                    break;
                                }
                            }
                            if (canInsert) {
                                for (int k = 0;k < subExplainList.size(); k++) {
                                    FieldAttrEntity attrEntity1 = subExplainList.get(k);
                                    if(Objects.equals(afterAttr,attrEntity1.getAttr())) {
                                        for (int j = 0; j < fieldAttrEntities.size(); j++) {
                                            subExplainList.add(j + k + 1, fieldAttrEntities.get(j));
                                        }
                                    }
                                }
                                fieldAttrEntity.getSubForm().setItems(subExplainList);
                                entity.setExplains(JSONObject.toJSONString(fieldAttrEntityList));
                            }
                            break;
                        }
                    }
                    if (canInsert) {
                        workOrderExplainModel.update(entity);
                    }
                }
            }else {
                List<PaasFormExplainEntity> entitys = paasFormExplainModel.getNoHandleExplainsByFindEntitys(param);
                for (PaasFormExplainEntity entity : entitys){
                    if (Objects.equals("[]", entity.getExplains())) {
                        continue;
                    }
                    boolean canInsert = true;
                    boolean parentCanInsert = true;
                    List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(entity.getExplains(),FieldAttrEntity.class);
                    int obj = 0;
                    if (Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode())) {
                        Iterator<FieldAttrEntity> iterator = fieldAttrEntityList.iterator();
                        while (iterator.hasNext()) {
                            FieldAttrEntity next = iterator.next();
                            if (Objects.equals(next.getAttr(), "text_13")) {
                                iterator.remove();
                                break;
                            }
                        }
                    }
                    for(int i = 0; i < fieldAttrEntityList.size(); i++){
                        //插入到当前字段后面
                        FieldAttrEntity fieldAttrEntity = fieldAttrEntityList.get(i);
                        if (parentAttrList.contains(fieldAttrEntity.getAttr())) {
                            parentCanInsert = false;
                            failList.add(entity.getId());
                            LOGGER.error(businessType + "业务类型" + corpid + "该公司已存在" + fieldAttrEntity.getAttr() + "字段");
                            break;
                        }
                        if (Objects.equals(FieldTypeEnum.SELECT_PRODUCT.getType(), fieldAttrEntity.getFieldType())) {
                            if (Objects.equals(businessType, XbbRefTypeEnum.PRODUCTION_ORDER.getCode()) && Objects.equals(fieldAttrEntity.getAttr(),ProductionOrderEnum.PRODUCT.getAttr())) {
                                continue;
                            }
                            if (Objects.isNull(fieldAttrEntity.getSubForm()) || Objects.isNull(fieldAttrEntity.getSubForm().getItems())) {
                                failList.add(entity.getId());
                                LOGGER.error(businessType + "业务类型关联产品没有subForm的corpid:" + entity.getCorpid() + "/解释id:" + entity.getId() + "/formId:" + entity.getFormId());
                                continue;
                            }
                            List<FieldAttrEntity> subExplainList = (List<FieldAttrEntity>)fieldAttrEntity.getSubForm().getItems();
                            for (int k = 0;k < subExplainList.size(); k++) {
                                FieldAttrEntity attrEntity1 = subExplainList.get(k);
                                if (attrList.contains(attrEntity1.getAttr())) {
                                    failList.add(entity.getId());
                                    LOGGER.error(businessType + "业务类型" + corpid + "该公司已存在" + attrEntity1.getAttr() + "字段");
                                    canInsert = false;
                                    break;
                                }
                            }
                            if (canInsert) {
                                for (int k = 0;k < subExplainList.size(); k++) {
                                    FieldAttrEntity attrEntity1 = subExplainList.get(k);
                                    if (needExpire) {
                                        if (Objects.equals(attrEntity1.getAttr(), SelectProductEnum.GUARANTEE_PERIOD.getAttr())) {
                                            if (!batchShelf) {
                                                attrEntity1.setVisible(0);
                                                attrEntity1.setEditHide(1);
                                                expireDateEntity.setVisible(0);
                                                expireDateEntity.setEditHide(1);
                                            }else {
                                                expireDateEntity.setVisible(1);
                                                expireDateEntity.setEditHide(0);
                                            }
                                            subExplainList.add(k + 1, expireDateEntity);
                                        } else if (Objects.equals(attrEntity1.getAttr(), SelectProductEnum.BATCH.getAttr()) || Objects.equals(attrEntity1.getAttr(), SelectProductEnum.PRODUCE_DATE.getAttr())) {
                                            if (!batchShelf) {
                                                attrEntity1.setVisible(0);
                                                attrEntity1.setEditHide(1);
                                            }
                                        }
                                    }
                                    if(Objects.equals(afterAttr,attrEntity1.getAttr())) {
                                        for (int j = 0; j < fieldAttrEntities.size(); j++) {
                                            FieldAttrEntity fieldAttr = fieldAttrEntities.get(j);
                                            if (Objects.equals(fieldAttr.getAttr(), SelectProductEnum.DETAIL_STATUS.getAttr())) {
                                                subExplainList.add(fieldAttr);
                                            }else {
                                                subExplainList.add(j + k + 1, fieldAttr);
                                            }
                                        }
                                    }
                                }
                                fieldAttrEntity.getSubForm().setItems(subExplainList);
                                entity.setExplains(JSONObject.toJSONString(fieldAttrEntityList));
                            }
                        }
                        if (insertParentFieldAttr) {
                            if (Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode())) {
                                if (Objects.equals(fieldAttrEntity.getAttr(), ContractEnum.EXPRESS_STATUS.getAttr()) && !parentAttrEntities.isEmpty()) {
                                    obj = i + 1;
                                }
                            }else if (Objects.equals(businessType, XbbRefTypeEnum.PURCHASE.getCode())) {
                                if (Objects.equals(fieldAttrEntity.getAttr(), PurchaseEnum.STATUS.getAttr()) && !parentAttrEntities.isEmpty()) {
                                    obj = i + 1;
                                }
                            }else if (Objects.equals(businessType, XbbRefTypeEnum.REFUND.getCode())) {
                                if (Objects.equals(fieldAttrEntity.getAttr(), RefundEnum.REFUND_REASON.getAttr()) && !parentAttrEntities.isEmpty()) {
                                    obj = i + 1;
                                }
                            }else if (Objects.equals(businessType, XbbRefTypeEnum.RETURNED_PURCHASE.getCode())) {
                                if (Objects.equals(fieldAttrEntity.getAttr(), ReturnedPurchaseEnum.TOTAL_MONEY.getAttr()) && !parentAttrEntities.isEmpty()) {
                                    obj = i + 1;
                                }
                            }else if (Objects.equals(businessType, XbbRefTypeEnum.TRANSFER.getCode())) {
                                if (Objects.equals(fieldAttrEntity.getAttr(), TransferEnum.SHEET_NO.getAttr()) && !parentAttrEntities.isEmpty()) {
                                    obj = i + 1;
                                }
                            }else if (Objects.equals(businessType, XbbRefTypeEnum.INVENTORY.getCode())) {
                                if (Objects.equals(fieldAttrEntity.getAttr(), InventoryEnum.SHEET_NO.getAttr()) && !parentAttrEntities.isEmpty()) {
                                    obj = i + 1;
                                }
                            }
                        }
                    }
                    if (obj != 0){
                        for (int i = 0; i < parentAttrEntities.size(); i++) {
                            fieldAttrEntityList.add(obj + i, parentAttrEntities.get(i));
                        }
                        entity.setExplains(JSONObject.toJSONString(fieldAttrEntityList));
                    }
                    if (canInsert && parentCanInsert) {
                        paasFormExplainModel.update(entity);
                    }
                }
            }

        }
        if (!failList.isEmpty()) {
            LOGGER.error(businessType + "部分更新成功，id " + failList + "更新失败");
        }

    }

    @Override
    public ScriptVO scriptContractProcessData(RepairContractDataDTO repairContractDataDTO) throws XbbException {
        ScriptVO scriptVO = new ScriptVO();
        List<String> corpidList = repairContractDataDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = companyModel.getCorpidList();
        }
        Integer startTimme = DateUtil.getInt();
        LOGGER.info("================审批流程中的合同存在回款单没有回款账户的数据更新结束=====================开始时间:"+startTimme);
        LOGGER.info("共有" + corpidList.size() + "家数据");
        int i = 0;
        for (String corpid : corpidList) {
            i++;
            LOGGER.info("现在是第" + i + "家公司");
            FundAccountEntity fundAccountEntity = fundAccountModel.getDefaultFundAccount(corpid);
            int pageSize = 500;
            Long idGte = 0L;
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(ParameterConstant.CORPID, corpid);
            param.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
            param.put("bussinessType", XbbRefTypeEnum.CONTRACT.getCode());
            param.put("flowStatusIn", Arrays.asList(FlowStatusEnum.APPROVAL_PENDING.getType(),FlowStatusEnum.IN_APPROVAL.getType()));
            boolean flag = true;
            int j = 0;
            while (flag) {
                LOGGER.info("当前是" + j++ + "页");
                param.put("pageSize", pageSize);
                param.put("orderByStr", "id asc");
                param.put("idGte", idGte);
                List<PaasProcessDataEntity> paasProcessDataEntityList = paasProcessDataModel.list(param);
                if (paasProcessDataEntityList.isEmpty()) {
                    flag = false;
                    continue;
                }
                PaasProcessDataEntity paasProcessData = paasProcessDataEntityList.get(paasProcessDataEntityList.size()-1);
                if ( Objects.nonNull(paasProcessData) ) {
                    idGte = paasProcessData.getId();
                }
                List<PaasProcessDataEntity> paasProcessDataList = new ArrayList<>(paasProcessDataEntityList.size());
                for (PaasProcessDataEntity paasProcessDataEntity : paasProcessDataEntityList ) {
                    String data = paasProcessDataEntity.getData();
                    JSONObject dataObject = JSON.parseObject(data);
                    String addPaymentSheetStr = dataObject.getString(ContractEnum.ADD_PAYMENT_SHEET.getAttr());
                    if ( Objects.nonNull(addPaymentSheetStr) ) {
                        JSONArray addPaymentSheetArr = JSON.parseArray(addPaymentSheetStr);
                        List<Object> paymentSheet = new ArrayList<>(addPaymentSheetArr.size());
                        if ( Objects.nonNull(fundAccountEntity) ) {
                            for (Object addPaymentSheetObj : addPaymentSheetArr) {
                                JSONObject addPaymentSheetObject = JSON.parseObject(addPaymentSheetObj.toString());
                                Object id = addPaymentSheetObject.get("id");
                                if ( Objects.isNull(id) ) {
                                    JSONObject paymentSheetData = addPaymentSheetObject.getJSONObject("data");
                                    paymentSheetData.put(PaymentSheetEnum.FUND_ACCOUNT.getAttr(), fundAccountEntity.getId().toString());
                                    paymentSheetData.put(PaymentSheetEnum.FUND_ACCOUNT_LINK_TEXT.getAttr(), fundAccountEntity.getName());
                                }
                                paymentSheet.add(addPaymentSheetObject);
                            }
                        }
                        dataObject.put(ContractEnum.ADD_PAYMENT_SHEET.getAttr(),paymentSheet);
                        paasProcessDataEntity.setData(JSONObject.toJSONString(dataObject));
                        paasProcessDataList.add(paasProcessDataEntity);
                    }
                }
                if ( CollectionsUtil.isNotEmpty(paasProcessDataList) ) {
                    paasProcessDataModel.updateBatchForAll(paasProcessDataList,corpid);
                }
            }
        }
        scriptVO.setMsg("总共更新" + i + "家合同数据");
        Integer endTimme = DateUtil.getInt();
        LOGGER.info("================审批流程中的合同存在回款单没有回款账户的数据更新结束=====================结束时间为:"+endTimme+"，====耗时为:"+(endTimme-startTimme));
        return scriptVO;
    }

    @Override
    public ScriptVO repairAddExplainProduct2(AllScriptDTO allScriptDTO) throws XbbException {
        long start = DateTimeUtil.getInt();
        LocaleContextHolder.setLocale(Locale.CHINA);
        List<String> corpidList = allScriptDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = companyModel.getCorpidList();
        }
        allScriptDTO.setCorpidList(corpidList);

        List<Integer> businessTypeList = Arrays.asList(XbbRefTypeEnum.CONTRACT.getCode(), XbbRefTypeEnum.PURCHASE.getCode(), XbbRefTypeEnum.PRODUCTION_ORDER.getCode(), XbbRefTypeEnum.WORK_ORDER.getCode());
        allScriptDTO.setOperate(RepairExplainEnum.ADD.getCode());
        for (Integer businessType : businessTypeList) {
            if (Objects.equals(businessType, XbbRefTypeEnum.CONTRACT.getCode())) {
                allScriptDTO.setAttr(ContractEnum.PRODUCT.getAttr());
                allScriptDTO.setAfterAttr(ContractProductEnum.MEMO.getAttr());
                allScriptDTO.setBusinessType(XbbRefTypeEnum.CONTRACT.getCode());
            }else if (Objects.equals(businessType, XbbRefTypeEnum.PURCHASE.getCode())){
                allScriptDTO.setAttr(PurchaseEnum.PRODUCT.getAttr());
                allScriptDTO.setAfterAttr(PurchaseProductEnum.MEMO.getAttr());
                allScriptDTO.setBusinessType(XbbRefTypeEnum.PURCHASE.getCode());
            }else if (Objects.equals(businessType, XbbRefTypeEnum.PRODUCTION_ORDER.getCode())){
                allScriptDTO.setAttr(ProductionOrderEnum.MATERIEL.getAttr());
                allScriptDTO.setAfterAttr(ProductionOrderMaterielProductEnum.UNIT.getAttr());
                allScriptDTO.setBusinessType(XbbRefTypeEnum.PRODUCTION_ORDER.getCode());
            }else if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())){
                allScriptDTO.setAttr(WorkOrderEnum.SPARE_PARTS.getAttr());
                allScriptDTO.setAfterAttr(WorkOrderProductEnum.UNIT.getAttr());
                allScriptDTO.setBusinessType(XbbRefTypeEnum.WORK_ORDER.getCode());
            }
            Class<?> clazz = getBusinessProductClass(businessType);
            Class<?> tempClazz = getBusinessProductTempClass(businessType);
            Class<?> parentClazz = getBusinessClass(businessType);
            Class<?> tempParentClazz = getBusinessTempClass(businessType);
            List<FieldAttrEntity> fieldAttrEntities = productPre(businessType, allScriptDTO.getAttr(), clazz, tempClazz);
            FieldAttrEntity expireDateEntitity = expireProductPre(businessType, allScriptDTO.getAttr(), clazz, tempClazz);
            List<FieldAttrEntity> parentAttrEntities = parentPre(businessType, allScriptDTO.getAttr(), parentClazz, tempParentClazz);
            RepairExplainEnum repairExplainEnum = RepairExplainEnum.getByCode(allScriptDTO.getOperate());

            switch (repairExplainEnum){
                case ADD:
                    addImproveExplainProduct(allScriptDTO, fieldAttrEntities, parentAttrEntities, expireDateEntitity);
                    break;
//                case DEL:
//                    delWorkOrderExplainProduct(allScriptDTO, clazz, tempClazz, allScriptDTO.getAttr());
                default:
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001,"未知操作");
            }
        }

        LOGGER.warn("consume:" + (DateTimeUtil.getInt() - start));
        return null;
    }

    @Override
    public ScriptVO fixContractMemo(FixContractDTO fixContractDTO) throws XbbException {
        long start = DateTimeUtil.getInt();
        Integer businessType = XbbRefTypeEnum.CONTRACT.getCode();

        List<String> corpidList = fixContractDTO.getCorpidList();
        if (corpidList.isEmpty()){
            corpidList = paasFormExplainModel.getCorpidList();
            corpidList.add("0");
        }

        String oldCostMemo = "合同成本 = 合同产品总成本 + 其他费用；其中“合同产品总成本”在实际出库前由预估产品成本计算而得，实际出库之后取实际产品成本计算而得，故而“合同成本”字段会根据实际情况进行变动及更新。";
        String oldProfitMemo = "合同毛利= 合同金额 - 合同成本";

        String newCostMemo = "合同成本= 合同产品总成本 - 退货产品成本 + 其他费用；其中“合同产品总成本”在实际出库前由预估产品成本计算而得，实际出库之后取实际产品成本计算而得。其中“退货产品成本”会在实际入库之后取实际产品成本计算而得。故而“合同成本”字段会根据实际情况进行变动及更新。(若历史数据不正确，请编辑合同订单并保存，系统会自动更正数据)";
        String newProfitMemo = "合同毛利= 合同金额 - 退货金额 - 合同成本 (若历史数据不正确，请编辑合同订单并保存，系统会自动更正数据)";
        // 剔除掉自己改过解释的公司
        Integer index = 1;
        List<Long> failList = new ArrayList<>();
        for (String corpid : corpidList) {
            LOGGER.warn("当前执行公司：" + corpid);
            LOGGER.warn(index + "/" + fixContractDTO.getCorpidList().size());
            index++;
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("del", 0);
            param.put("businessType", XbbRefTypeEnum.CONTRACT.getCode());
            if (fixContractDTO.getFormId() != null) {
                param.put("formId", fixContractDTO.getFormId());
            }
            List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.getNoHandleExplainsByFindEntitys(param);
            List<PaasFormExplainEntity> updateList = new ArrayList<>();

            for (PaasFormExplainEntity entity : paasFormExplainEntityList) {
                boolean update = false;
                List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(entity.getExplains(), FieldAttrEntity.class);
                if(Objects.equals(fieldAttrEntityList.size(), BasicConstant.ZERO)){
                    continue;
                }
                for (FieldAttrEntity fieldAttrEntity : fieldAttrEntityList) {
                    boolean updateCost = Objects.equals(fieldAttrEntity.getAttr(),ContractEnum.CONTRACT_COST.getAttr()) && Objects.equals(fieldAttrEntity.getMemo(), oldCostMemo);
                    boolean updateProfit = Objects.equals(fieldAttrEntity.getAttr(),ContractEnum.GROSS_PROFIT.getAttr()) && Objects.equals(fieldAttrEntity.getMemo(), oldProfitMemo);
                    if (updateCost) {
                        fieldAttrEntity.setMemo(newCostMemo);
                        update = true;
                    }
                    if (updateProfit) {
                        fieldAttrEntity.setMemo(newProfitMemo);
                        update = true;
                    }
                }
                if (update) {
                    entity.setExplains(JSONArray.toJSONString(fieldAttrEntityList));
                    updateList.add(entity);
                } else {
                    failList.add(entity.getId());
                }
            }
            if (updateList.isEmpty()) {
//                throw new XbbException(ErrorCodeEnum.API_SUCCESS, "未找到更新内容");
            } else {
                paasFormExplainModel.updateBatchExplains(updateList,corpid);
            }
        }

        String key = PaasConstant.DEFAULT_DATA_CORPID + "_" + businessType;
        paasRedisHelper.removeValue(RedisPrefixConstant.FIELD_EXPLANATION, key);
        LOGGER.warn("consume:" + (DateTimeUtil.getInt() - start));

        if (!failList.isEmpty()) {
            throw new XbbException(ErrorCodeEnum.API_SUCCESS, "部分更新成功，id " + failList + "更新失败");
        }
        return null;
    }

    @Override
    public ScriptVO fixProductUnit(FixDataJobDTO fixDataJobDTO) throws XbbException {

        long start = DateTimeUtil.getInt();
        List<String> corpidList = fixDataJobDTO.getCorpidList();
        if (corpidList.isEmpty()){
            return null;
        }
        Integer index = 1;
        List<Long> failList = new ArrayList<>();
        for (String corpid : corpidList) {
            LOGGER.warn("当前执行公司：" + corpid);
            LOGGER.warn(index + "/" + fixDataJobDTO.getCorpidList().size());
            index++;
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("corpid", corpid);
            param.put("del", 0);
            param.put("businessType", XbbRefTypeEnum.PRODUCT.getCode());
            List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.getNoHandleExplainsByFindEntitys(param);
            if (paasFormExplainEntityList.isEmpty()) {
                continue;
            }
            for (PaasFormExplainEntity entity : paasFormExplainEntityList) {
                List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(entity.getExplains(), FieldAttrEntity.class);
                if(Objects.equals(fieldAttrEntityList.size(), BasicConstant.ZERO)){
                    continue;
                }
                for (FieldAttrEntity fieldAttrEntity : fieldAttrEntityList) {
                    if (Objects.equals(fieldAttrEntity.getAttr(), ProductEnum.UNIT.getAttr())) {
                        List<ItemPoJo> items = fieldAttrEntity.getItems();
                        for (ItemPoJo item : items) {
                            if (Objects.equals(item.getValue(),"选项值1")) {
                                item.setValue("1");
                            } else if (Objects.equals(item.getValue(),"选项值2")) {
                                item.setValue("2");
                            } else if (Objects.equals(item.getValue(),"选项值3")) {
                                item.setValue("3");
                            }
                        }
                        break;
                    }
                }
                entity.setExplains(JSON.toJSONString(fieldAttrEntityList));
                paasFormExplainModel.update(entity);
            }
        }
        LOGGER.warn("consume:" + (DateTimeUtil.getInt() - start));
        if (!failList.isEmpty()) {
            throw new XbbException(ErrorCodeEnum.API_SUCCESS, "部分更新成功，id " + failList + "更新失败");
        }
        return null;

    }

    @Override
    public ScriptVO addCustomerExplain(AllScriptDTO allScriptDTO) throws XbbException {
        long start = DateTimeUtil.getInt();
        Integer businessType = allScriptDTO.getBusinessType();
        List<String> corpidList = allScriptDTO.getCorpidList();
        if ( corpidList.isEmpty() ) {
            corpidList = paasFormExplainModel.getCorpidList();
            corpidList.add("0");
        }
        allScriptDTO.setCorpidList(corpidList);
        List<String> attrList = Arrays.asList("text_81","text_82","num_61","array_31");
        LOGGER.warn(allScriptDTO.getCorpidList().size() + "家公司");
        Integer index = 1;
        List<Long> failList = new ArrayList<>();
        RepairExplainEnum repairExplainEnum = RepairExplainEnum.getByCode(allScriptDTO.getOperate());
        if (Objects.equals(businessType, XbbRefTypeEnum.WORK_ORDER.getCode())) {

        }else {
            switch (repairExplainEnum){
                case DEL:
                    for ( String corpid : allScriptDTO.getCorpidList() ) {
                        Boolean update = false;
                        LOGGER.info(index + "/" + allScriptDTO.getCorpidList().size());
                        index ++;
                        Map<String,Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        param.put("corpid",corpid);
                        param.put("del",0);
                        param.put("businessType",businessType);
                        if ( allScriptDTO.getFormId() != null ) {
                            param.put("formId", allScriptDTO.getFormId());
                        }
                        List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.getNoHandleExplainsByFindEntitys(param);
                        List<PaasFormExplainEntity> updateList = new ArrayList<>();
                        for (PaasFormExplainEntity entity : paasFormExplainEntityList){
                            List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(entity.getExplains(),FieldAttrEntity.class);
                            Iterator<FieldAttrEntity> iterator = fieldAttrEntityList.iterator();
                            while (iterator.hasNext()){
                                FieldAttrEntity fieldAttrEntity = iterator.next();
                                for ( String attr : attrList ) {
                                    if (Objects.equals(fieldAttrEntity.getAttr(),attr) && Objects.equals(fieldAttrEntity.getIsRedundant(),0)){
                                        iterator.remove();
                                        update = true;
                                    }
                                }
                            }
                            if (update){
                                entity.setExplains(JSONArray.toJSONString(fieldAttrEntityList));
                                updateList.add(entity);
                            } else {
                                failList.add(entity.getId());
                            }
                        }
                        if (CollectionsUtil.isNotEmpty(updateList)){
                            paasFormExplainModel.updateBatch(updateList,corpid);
                        }
                    }
                    break;
                case ADD:
                    for ( String corpid : allScriptDTO.getCorpidList() ) {
                        LOGGER.warn(index + "/" + allScriptDTO.getCorpidList().size());
                        index++;
                        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                        param.put("corpid", corpid);
                        param.put("del", 0);
                        param.put("businessType", businessType);
                        if ( allScriptDTO.getFormId() != null ) {
                            param.put("formId", allScriptDTO.getFormId());
                        }
                        List<PaasFormExplainEntity> paasFormExplainEntityList = paasFormExplainModel.getNoHandleExplainsByFindEntitys(param);
                        List<PaasFormExplainEntity> updateList = new ArrayList<>(paasFormExplainEntityList.size());
                        for ( PaasFormExplainEntity entity : paasFormExplainEntityList ) {
                            LOGGER.info("corpid:"+corpid+"     ---formId:" + entity.getFormId());
                            List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(entity.getExplains(), FieldAttrEntity.class);
                            Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(entity.getExplains(), null);
                            List<FieldAttrEntity> newFieldAttrEntityList = new ArrayList<>(fieldAttrEntityList.size());
                            for ( int i = 0; i < fieldAttrEntityList.size(); i++ ) {
                                //插入到当前字段后面
                                FieldAttrEntity oldFieldAttrEntity = fieldAttrEntityList.get(i);
                                if ( Objects.equals(CustomerManagementEnum.NAME.getAttr(), oldFieldAttrEntity.getAttr()) && !explainMap.containsKey(CustomerManagementEnum.SCORE.getAttr()) ) {
                                    FieldAttrEntity fieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                                    TempCustomerManagementEnum.initScore(fieldAttrEntity);
                                    BeanUtil.copyProperties(CustomerManagementEnum.SCORE, fieldAttrEntity);
                                    fieldAttrEntity.setAttrType(FieldTypeEnum.getFieldTypeEnum(CustomerManagementEnum.SCORE.getFieldType()).getAlias());
                                    newFieldAttrEntityList.add(fieldAttrEntity);
                                }
                                if ( Objects.equals(CustomerManagementEnum.NAME.getAttr(), oldFieldAttrEntity.getAttr()) && !explainMap.containsKey(CustomerManagementEnum.CLUE_ID.getAttr()) ) {
                                    FieldAttrEntity fieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                                    TempCustomerManagementEnum.initClueId(fieldAttrEntity);
                                    fieldAttrEntity.setFieldId(UUID.randomUUID().toString());
                                    BeanUtil.copyProperties(CustomerManagementEnum.CLUE_ID, fieldAttrEntity);
                                    fieldAttrEntity.setAttrType(FieldTypeEnum.getFieldTypeEnum(CustomerManagementEnum.CLUE_ID.getFieldType()).getAlias());
                                    newFieldAttrEntityList.add(fieldAttrEntity);
                                }
                                if ( Objects.equals(CustomerManagementEnum.NAME.getAttr(), oldFieldAttrEntity.getAttr()) && !explainMap.containsKey(CustomerManagementEnum.CLUE_NAME_ID.getAttr()) ) {
                                    FieldAttrEntity fieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                                    BeanUtil.copyProperties(CustomerManagementEnum.CLUE_NAME_ID, fieldAttrEntity);
                                    fieldAttrEntity.setAttrType(FieldTypeEnum.getFieldTypeEnum(CustomerManagementEnum.CLUE_NAME_ID.getFieldType()).getAlias());
                                    fieldAttrEntity.setFieldId(UUID.randomUUID().toString());
                                    newFieldAttrEntityList.add(fieldAttrEntity);
                                }
                                if ( Objects.equals(CustomerManagementEnum.GENRE.getAttr(), oldFieldAttrEntity.getAttr()) && !explainMap.containsKey(CustomerManagementEnum.LABEL.getAttr()) ) {
                                    FieldAttrEntity fieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                                    BeanUtil.copyProperties(CustomerManagementEnum.LABEL, fieldAttrEntity);
                                    fieldAttrEntity.setAttrType(FieldTypeEnum.getFieldTypeEnum(CustomerManagementEnum.LABEL.getFieldType()).getAlias());
                                    fieldAttrEntity.setFieldId(UUID.randomUUID().toString());
                                    newFieldAttrEntityList.add(fieldAttrEntity);
                                }
                                newFieldAttrEntityList.add(oldFieldAttrEntity);
                            }
                            entity.setExplains(JSONObject.toJSONString(newFieldAttrEntityList));
                            updateList.add(entity);
                        }
                        if ( CollectionsUtil.isNotEmpty(updateList) ) {
                            paasFormExplainModel.updateBatch(updateList,corpid);
                        }
                    }
                    break;
                default:
                    throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001,"未知操作");
            }
        }
        String key = PaasConstant.DEFAULT_DATA_CORPID + "_" + businessType;
        paasRedisHelper.removeValue(RedisPrefixConstant.FIELD_EXPLANATION, key);
        LOGGER.warn("consume:" + (DateTimeUtil.getInt() - start));
        if ( failList.isEmpty() ) {
            throw new XbbException(ErrorCodeEnum.API_SUCCESS, "更新成功");
        } else {
            throw new XbbException(ErrorCodeEnum.API_SUCCESS, "部分更新成功，id " + failList + "更新失败");
        }
    }

    @Override
    public ScriptVO fineClueMatchSearch(FieldSetDTO fieldSetDTO) throws XbbException {
        ScriptVO scriptVO = new ScriptVO();
        long start = DateTimeUtil.getInt();
        List<String> corpidList = fieldSetDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            // 查询搜客公司
            corpidList = searchCustomerCompanyModel.getCorpidListWithType(SoukeMealEnum.BUSINESS.getType());
        }
        Integer index = 1;
        Integer updateCount = 0;
        List<String> errorCorpidList = new ArrayList<>();
        Map<String, Object> param = new HashMap<>();
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("businessTypeIn", Collections.singletonList(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()));

        for (String corpid : corpidList) {
            LOGGER.warn("当前执行公司：" + corpid);
            LOGGER.warn(index + "/" + corpidList.size());
            index++;
            SearchCustomerCompanyEntity soukeCompanyEntity = searchCustomerCompanyModel.getByCorpid(corpid, SoukeMealEnum.BUSINESS.getType());
            if (soukeCompanyEntity == null) {
                continue;
            }
            // 获取客户表单
            param.put(StringConstant.CORPID, corpid);
            List<PaasFormExplainEntity> formExplainEntityList = paasFormExplainModel.findEntitys(param);
            List<PaasFormExplainEntity> updateExplainList = new ArrayList<>();
            for (PaasFormExplainEntity entity : formExplainEntityList) {
                List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(entity.getExplains(), FieldAttrEntity.class);
                if (CollectionsUtil.isEmpty(fieldAttrEntityList)) {
                    continue;
                }
                boolean updateFlag = false;
                for (FieldAttrEntity fieldAttrEntity : fieldAttrEntityList) {
                    DefaultAttrPoJo defaultAttrPoJo = fieldAttrEntity.getDefaultAttr();
                    // 是否为销客工商查询字段
                    if (Objects.isNull(defaultAttrPoJo) || !Objects.equals(defaultAttrPoJo.getDefaultType(), DefaultTypeEnum.BUSINESS_FIELD.getAlias())) {
                        continue;
                    }
                    BusinessFieldPojo businessFieldPojo = defaultAttrPoJo.getBusinessMatchAttr();
                    if (Objects.isNull(businessFieldPojo)) {
                        continue;
                    }
                    BusinessFineClueEnum businessFineClueEnum = FineClueMatchSearchEnum.getByCode(businessFieldPojo.getCode());
                    // 没有对应关系
                    if (Objects.isNull(businessFineClueEnum)) {
                        continue;
                    }
                    updateFlag = true;

                    businessFieldPojo.setAttr(businessFineClueEnum.getAttr());
                    businessFieldPojo.setCode(businessFineClueEnum.getCode());
                    businessFieldPojo.setParent(businessFineClueEnum.getParent());
                    businessFieldPojo.setSource(businessFineClueEnum.getSource());
                    businessFieldPojo.setAttrName(businessFineClueEnum.getAttrName());

                    defaultAttrPoJo.setDefaultType("fineClue");
                    // 有子表单字段
                    if (CollectionsUtil.isNotEmpty(businessFieldPojo.getChildField())) {
                        for (BusinessFieldPojo subBusinessPojo : businessFieldPojo.getChildField()) {
                            BusinessFineClueEnum subFineClueEnum = FineClueMatchSearchEnum.getByCode(subBusinessPojo.getCode());
                            if (Objects.isNull(subFineClueEnum)) {
                                continue;
                            }
                            subBusinessPojo.setAttr(subFineClueEnum.getAttr());
                            subBusinessPojo.setCode(subFineClueEnum.getCode());
                            subBusinessPojo.setParent(subFineClueEnum.getParent());
                            subBusinessPojo.setSource(subFineClueEnum.getSource());
                            subBusinessPojo.setAttrName(subFineClueEnum.getAttrName());
                        }
                    }
                    // 是否为子表单
                    if (Objects.isNull(fieldAttrEntity.getSubForm()) || Objects.isNull(fieldAttrEntity.getSubForm().getItems())) {
                        continue;
                    }
                    List<FieldAttrEntity> subExplainList = (List<FieldAttrEntity>) fieldAttrEntity.getSubForm().getItems();
                    for (FieldAttrEntity subAttrEntity : subExplainList) {
                        DefaultAttrPoJo subAttrPoJo = subAttrEntity.getDefaultAttr();
                        // 是否为销客工商查询字段
                        if (Objects.isNull(subAttrPoJo) || !Objects.equals(subAttrPoJo.getDefaultType(), DefaultTypeEnum.BUSINESS_FIELD.getAlias())) {
                            continue;
                        }
                        BusinessFieldPojo subFieldPojo = subAttrPoJo.getBusinessMatchAttr();
                        BusinessFineClueEnum subFineClueEnum = FineClueMatchSearchEnum.getByCode(subFieldPojo.getCode());
                        // 没有对应关系
                        if (Objects.isNull(subFineClueEnum)) {
                            continue;
                        }
                        subFieldPojo.setAttr(subFineClueEnum.getAttr());
                        subFieldPojo.setCode(subFineClueEnum.getCode());
                        subFieldPojo.setParent(subFineClueEnum.getParent());
                        subFieldPojo.setSource(subFineClueEnum.getSource());
                        subFieldPojo.setAttrName(subFineClueEnum.getAttrName());

                        subAttrPoJo.setDefaultType("fineClue");
                    }
                }
                if (updateFlag) {
                    entity.setExplains(JSONObject.toJSONString(fieldAttrEntityList));
                    updateExplainList.add(entity);
                }
            }
            if (CollectionsUtil.isNotEmpty(updateExplainList)) {

                try {
                    paasFormExplainModel.updateBatch(updateExplainList, corpid);
                    updateCount++;
                } catch (Exception e) {
                    errorCorpidList.add(corpid);
                }
            }
        }

        LOGGER.warn("consume:" + (DateTimeUtil.getInt() - start) + "  更新失败公司：" + errorCorpidList.toString());
        scriptVO.setMsg("总共更新" + updateCount + "家公司解释");
        return scriptVO;
    }


    @Override
    public ScriptVO addCustomerStage(AllScriptDTO allScriptDTO) throws XbbException {
        LOGGER.warn("开始处理表单解释");
        ScriptVO scriptVO = new ScriptVO();
        long currentTime = DateTimeUtil.getInt();
        List<String> corpidList = allScriptDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = paasFormExplainModel.getCorpidList();
            corpidList.add("0");
        }
        Integer pageSize = allScriptDTO.getPageSize();
        if (Objects.isNull(pageSize)) {
            pageSize = 1000;
        }
        int totalCount = corpidList.size();
        int pageNum = totalCount % pageSize > 0 ? totalCount / pageSize + 1 : totalCount / pageSize;
        for (int currentPage = 1; currentPage <= pageNum; currentPage++) {
            int startIndex = (currentPage - 1) * pageSize;
            int endIndex = currentPage * pageSize;
            if (Objects.equals(currentPage, pageNum)) {
                endIndex = totalCount;
            }
            LOGGER.warn("开始执行{}——{}家公司，进度{}/{}", startIndex, endIndex, currentPage, pageNum);

            List<String> currentPageCorpidList = corpidList.subList(startIndex, endIndex);
            Map<String, Object> param = new HashMap<>();
            param.put("columns", "id,business_type,explains");
            param.put("corpidIn", currentPageCorpidList);
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("distributorMark", DistributorMarkEnum.OTHER.getCode());
            param.put("businessTypeIn", Lists.newArrayList(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), XbbRefTypeEnum.CLUE.getCode(), XbbRefTypeEnum.SALES_OPPORTUNITY.getCode()));
            List<PaasFormExplainEntity> formExplainEntityList = paasFormExplainModel.findEntitys(param);
            if (CollectionsUtil.isEmpty(formExplainEntityList)) {
                continue;
            }
            List<PaasFormExplainEntity> updateList = new ArrayList<>(formExplainEntityList.size());
            for (PaasFormExplainEntity entity : formExplainEntityList) {
                    Integer businessType = entity.getBusinessType();
                    String explains = entity.getExplains();
                    if (StringUtil.isEmpty(entity.getExplains())) {
                        continue;
                    }
                    List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(explains, FieldAttrEntity.class);
                    if (CollectionsUtil.isEmpty(fieldAttrEntityList)) {
                        continue;
                    }
                    List<FieldAttrEntity> newFieldAttrEntityList = new ArrayList<>(fieldAttrEntityList.size());
                    boolean stageProcessIdBool  = true;
                    boolean stageIdBool  = true;
                    boolean stageRatioBool  = true;
                    if (Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), businessType)) {
                        for (int i = 0; i < fieldAttrEntityList.size(); i++) {
                            FieldAttrEntity fieldAttrEntity = fieldAttrEntityList.get(i);
                            String attr = fieldAttrEntity.getAttr();
                            if (Objects.equals(attr, CustomerManagementEnum.CUSTOMER_STAGE.getAttr())) {
                                fieldAttrEntity.setFieldType(FieldTypeEnum.STAGE_THRUSTER.getType());
                            }
                            newFieldAttrEntityList.add(fieldAttrEntity);
                            if (Objects.equals(CustomerManagementEnum.STAGE_PROCESS_ID.getAttr(), attr)) {
                                stageProcessIdBool = false;
                            } else if (Objects.equals(CustomerManagementEnum.STAGE_ID.getAttr(), attr)) {
                                stageIdBool = false;
                            } else if (Objects.equals(CustomerManagementEnum.STAGE_RATIO.getAttr(), attr)) {
                                stageRatioBool = false;
                            }
                        }
                        if (stageProcessIdBool){
                            //添加阶段流程id
                            FieldAttrEntity stageProcessId = InitExplainsHelper.getNewFieldAttrEntity();
                            BeanUtil.copyProperties(CustomerManagementEnum.STAGE_PROCESS_ID, stageProcessId);
                            stageProcessId.setAttrNameEn(CustomerManagementEnum.STAGE_PROCESS_ID.getAttrName());
                            stageProcessId.setDefaultName(CustomerManagementEnum.STAGE_PROCESS_ID.getAttrName());
                            stageProcessId.setAttrType("long");
                            stageProcessId.setIsRedundant(0);
                            stageProcessId.setEditable(0);
                            newFieldAttrEntityList.add(stageProcessId);
                        }
                        if (stageIdBool){
                            //添加阶段id
                            FieldAttrEntity stageId = InitExplainsHelper.getNewFieldAttrEntity();
                            BeanUtil.copyProperties(CustomerManagementEnum.STAGE_ID, stageId);
                            stageId.setAttrNameEn(CustomerManagementEnum.STAGE_ID.getAttrName());
                            stageId.setDefaultName(CustomerManagementEnum.STAGE_ID.getAttrName());
                            stageId.setAttrType("long");
                            stageId.setIsRedundant(0);
                            stageId.setEditable(0);
                            newFieldAttrEntityList.add(stageId);
                        }
                        if (stageRatioBool){
                            //添加阶段比例
                            FieldAttrEntity stageRatio = InitExplainsHelper.getNewFieldAttrEntity();
                            BeanUtil.copyProperties(CustomerManagementEnum.STAGE_RATIO, stageRatio);
                            stageRatio.setAttrNameEn(CustomerManagementEnum.STAGE_RATIO.getAttrName());
                            stageRatio.setDefaultName(CustomerManagementEnum.STAGE_RATIO.getAttrName());
                            stageRatio.setAttrType("long");
                            stageRatio.setIsRedundant(0);
                            stageRatio.setIsOpen(0);
                            stageRatio.setEditable(0);
                            stageRatio.setShowEditable(0);
                            stageRatio.setAccuracy(0);
                            newFieldAttrEntityList.add(stageRatio);
                        }
                    } else if (Objects.equals(XbbRefTypeEnum.CLUE.getCode(), businessType)) {
                        for (int i = 0; i < fieldAttrEntityList.size(); i++) {
                            FieldAttrEntity fieldAttrEntity = fieldAttrEntityList.get(i);
                            String attr = fieldAttrEntity.getAttr();
                            if (Objects.equals(attr, ClueEnum.CLUE_STAGE.getAttr())) {
                                fieldAttrEntity.setFieldType(FieldTypeEnum.STAGE_THRUSTER.getType());
                            }
                            newFieldAttrEntityList.add(fieldAttrEntity);
                            if (Objects.equals(ClueEnum.STAGE_PROCESS_ID.getAttr(), attr)) {
                                stageProcessIdBool = false;
                            } else if (Objects.equals(ClueEnum.STAGE_ID.getAttr(), attr)) {
                                stageIdBool = false;
                            } else if (Objects.equals(ClueEnum.STAGE_RATIO.getAttr(), attr)) {
                                stageRatioBool = false;
                            }
                        }
                        if (stageProcessIdBool){
                            //添加阶段流程id
                            FieldAttrEntity stageProcessId = InitExplainsHelper.getNewFieldAttrEntity();
                            BeanUtil.copyProperties(ClueEnum.STAGE_PROCESS_ID, stageProcessId);
                            stageProcessId.setAttrNameEn(ClueEnum.STAGE_PROCESS_ID.getAttrName());
                            stageProcessId.setDefaultName(ClueEnum.STAGE_PROCESS_ID.getAttrName());
                            stageProcessId.setAttrType("long");
                            stageProcessId.setIsRedundant(0);
                            stageProcessId.setEditable(0);
                            newFieldAttrEntityList.add(stageProcessId);
                        }
                        if (stageIdBool){
                            //添加阶段id
                            FieldAttrEntity stageId = InitExplainsHelper.getNewFieldAttrEntity();
                            BeanUtil.copyProperties(ClueEnum.STAGE_ID, stageId);
                            stageId.setAttrNameEn(ClueEnum.STAGE_ID.getAttrName());
                            stageId.setDefaultName(ClueEnum.STAGE_ID.getAttrName());
                            stageId.setEditable(0);
                            stageId.setAttrType("long");
                            stageId.setIsRedundant(0);
                            newFieldAttrEntityList.add(stageId);
                        }
                        if (stageRatioBool) {
                            //添加阶段比例
                            FieldAttrEntity stageRatio = InitExplainsHelper.getNewFieldAttrEntity();
                            BeanUtil.copyProperties(ClueEnum.STAGE_RATIO, stageRatio);
                            stageRatio.setAttrNameEn(ClueEnum.STAGE_RATIO.getAttrName());
                            stageRatio.setDefaultName(ClueEnum.STAGE_RATIO.getAttrName());
                            stageRatio.setEditable(0);
                            stageRatio.setAttrType("long");
                            stageRatio.setIsRedundant(0);
                            stageRatio.setIsOpen(0);
                            stageRatio.setShowEditable(0);
                            stageRatio.setAccuracy(0);
                            newFieldAttrEntityList.add(stageRatio);
                        }
                    } else if (Objects.equals(XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), businessType)) {
                        for (int i = 0; i < fieldAttrEntityList.size(); i++) {
                            FieldAttrEntity fieldAttrEntity = fieldAttrEntityList.get(i);
                            String attr = fieldAttrEntity.getAttr();
                            if (Objects.equals(attr, SalesOpportunityEnum.SALE_STAGE.getAttr())) {
                                fieldAttrEntity.setFieldType(FieldTypeEnum.STAGE_THRUSTER.getType());
                            }
                            newFieldAttrEntityList.add(fieldAttrEntity);
                            if (Objects.equals(SalesOpportunityEnum.STAGE_PROCESS_ID.getAttr(), attr)) {
                                stageProcessIdBool = false;
                            } else if (Objects.equals(SalesOpportunityEnum.STAGE_ID.getAttr(), attr)) {
                                stageIdBool = false;
                            } else if (Objects.equals(SalesOpportunityEnum.STAGE_RATIO.getAttr(), attr)) {
                                stageRatioBool = false;
                            }
                        }
                        if (stageProcessIdBool){
                            //添加阶段流程id
                            FieldAttrEntity stageProcessId = InitExplainsHelper.getNewFieldAttrEntity();
                            BeanUtil.copyProperties(SalesOpportunityEnum.STAGE_PROCESS_ID, stageProcessId);
                            stageProcessId.setAttrNameEn(SalesOpportunityEnum.STAGE_PROCESS_ID.getAttrName());
                            stageProcessId.setDefaultName(SalesOpportunityEnum.STAGE_PROCESS_ID.getAttrName());
                            stageProcessId.setEditable(0);
                            stageProcessId.setAttrType("long");
                            stageProcessId.setIsRedundant(0);
                            newFieldAttrEntityList.add(stageProcessId);
                        }
                        if (stageIdBool){
                            //添加阶段id
                            FieldAttrEntity stageId = InitExplainsHelper.getNewFieldAttrEntity();
                            BeanUtil.copyProperties(SalesOpportunityEnum.STAGE_ID, stageId);
                            stageId.setAttrNameEn(SalesOpportunityEnum.STAGE_ID.getAttrName());
                            stageId.setDefaultName(SalesOpportunityEnum.STAGE_ID.getAttrName());
                            stageId.setEditable(0);
                            stageId.setAttrType("long");
                            stageId.setIsRedundant(0);
                            newFieldAttrEntityList.add(stageId);
                        }
                        if (stageRatioBool){
                            //添加阶段比例
                            FieldAttrEntity stageRatio = InitExplainsHelper.getNewFieldAttrEntity();
                            BeanUtil.copyProperties(SalesOpportunityEnum.STAGE_RATIO, stageRatio);
                            stageRatio.setAttrNameEn(SalesOpportunityEnum.STAGE_RATIO.getAttrName());
                            stageRatio.setDefaultName(SalesOpportunityEnum.STAGE_RATIO.getAttrName());
                            stageRatio.setEditable(0);
                            stageRatio.setAttrType("long");
                            stageRatio.setIsRedundant(0);
                            stageRatio.setIsOpen(1);
                            stageRatio.setShowEditable(0);
                            stageRatio.setAccuracy(0);
                            newFieldAttrEntityList.add(stageRatio);
                        }
                    }
                    entity.setExplains(JSONObject.toJSONString(newFieldAttrEntityList));
                    updateList.add(entity);
            }
            if (CollectionsUtil.isNotEmpty(updateList)) {
                    paasFormExplainModel.updateBatchExplains(updateList);
            }
        }
        LOGGER.warn("客户、机会、线索表单解释新增字段完成，耗时{}", DateTimeUtil.getInt() - currentTime);
        // 删除机会的默认解释缓存
        String key = "0" + "_" + XbbRefTypeEnum.SALES_OPPORTUNITY.getCode() + "_" + DistributorMarkEnum.OTHER.getCode();
        paasRedisHelper.removeValue(RedisPrefixConstant.FIELD_EXPLANATION, key);
        LOGGER.warn("删除机会的默认解释缓存");
        return scriptVO;
    }

    @Override
    public ScriptVO addPublicPoolField(AllScriptDTO allScriptDTO) throws XbbException {
        LOGGER.warn("开始处理表单解释");
        ScriptVO scriptVO = new ScriptVO();
        long currentTime = DateTimeUtil.getInt();
        List<String> corpidList = allScriptDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = paasFormExplainModel.getCorpidList();
            corpidList.add("0");
        }
        Integer pageSize = allScriptDTO.getPageSize();
        if (Objects.isNull(pageSize)) {
            pageSize = 1000;
        }
        int totalCount = corpidList.size();
        int pageNum = totalCount % pageSize > 0 ? totalCount / pageSize + 1 : totalCount / pageSize;
        for (int currentPage = 1; currentPage <= pageNum; currentPage++) {
            int startIndex = (currentPage - 1) * pageSize;
            int endIndex = currentPage * pageSize;
            if (Objects.equals(currentPage, pageNum)) {
                endIndex = totalCount;
            }
            LOGGER.warn("开始执行{}——{}家公司，进度{}/{}", startIndex, endIndex, currentPage, pageNum);

            List<String> currentPageCorpidList = corpidList.subList(startIndex, endIndex);
            Map<String, Object> param = new HashMap<>();
            param.put("columns", "id,corpid,business_type,explains");
            param.put("corpidIn", currentPageCorpidList);
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("distributorMark", DistributorMarkEnum.OTHER.getCode());
            param.put("businessTypeIn", Lists.newArrayList(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), XbbRefTypeEnum.CLUE.getCode()));
            List<PaasFormExplainEntity> formExplainEntityList = paasFormExplainModel.findEntitys(param);
            if (CollectionsUtil.isEmpty(formExplainEntityList)) {
                continue;
            }
            List<PaasFormExplainEntity> updateList = new ArrayList<>(formExplainEntityList.size());
            for (PaasFormExplainEntity entity : formExplainEntityList) {
                Integer businessType = entity.getBusinessType();
                String explains = entity.getExplains();
                if (StringUtil.isEmpty(entity.getExplains())) {
                    continue;
                }
                List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(explains, FieldAttrEntity.class);
                if (CollectionsUtil.isEmpty(fieldAttrEntityList)) {
                    continue;
                }
                List<FieldAttrEntity> newFieldAttrEntityList = new ArrayList<>(fieldAttrEntityList.size());
                boolean customerBackNumExits = true;
                boolean customerPublicGroupExits = true;
                boolean contractSignDateExits = true;
                boolean opportunityAddDateExits = true;
                boolean clueBackNumExits = true;
                boolean cluePublicGroupExits = true;
                //全局判断，如果已经刷过数据则不用执行update
                boolean isUpdate = true;
                if (Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), businessType)) {
                    for (FieldAttrEntity fieldAttrEntity : fieldAttrEntityList) {
                        //新增的字段放在老的字段后面
                        newFieldAttrEntityList.add(fieldAttrEntity);
                        //如果该字段已经存在，不再需要添加该字段
                        String attr = fieldAttrEntity.getAttr();
                        if (Objects.equals(CustomerManagementEnum.BACK_NUM.getAttr(), attr)) {
                            customerBackNumExits = false;
                        } else if (Objects.equals(CustomerManagementEnum.PUBLIC_GROUP.getAttr(), attr)) {
                            customerPublicGroupExits = false;
                        } else if (Objects.equals(CustomerManagementEnum.CONTRACT_SIGN_DATE.getAttr(), attr)) {
                            contractSignDateExits = false;
                        } else if (Objects.equals(CustomerManagementEnum.OPPORTUNITY_ADD_DATE.getAttr(), attr)) {
                            opportunityAddDateExits = false;
                        }
                    }

                    if (!customerBackNumExits && !customerPublicGroupExits && !contractSignDateExits && !opportunityAddDateExits) {
                        isUpdate = false;
                    }

                    if (customerBackNumExits) {
                        //客户的退回次数字段
                        FieldAttrEntity fieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                        TempCustomerManagementEnum.initBackNum(fieldAttrEntity);
                        BeanUtil.copyProperties(CustomerManagementEnum.BACK_NUM, fieldAttrEntity);
                        fieldAttrEntity.setAttrType(FieldTypeEnum.NUM.getEsalias());
                        fieldAttrEntity.setAccuracy(0);
                        newFieldAttrEntityList.add(fieldAttrEntity);
                    }
                    //旗舰版公司才刷该字段
                    if (customerPublicGroupExits) {
                        //客户的所属公海 公海分组字段是旗舰版才需要刷
                        FieldAttrEntity fieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                        TempCustomerManagementEnum.initPublicGroup(fieldAttrEntity);
                        BeanUtil.copyProperties(CustomerManagementEnum.PUBLIC_GROUP, fieldAttrEntity);
                        fieldAttrEntity.setAttrType(FieldTypeEnum.TEXT.getEsalias());
                        newFieldAttrEntityList.add(fieldAttrEntity);
                    }
                    if (contractSignDateExits) {
                        //合同最后签订时间
                        FieldAttrEntity fieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                        BeanUtil.copyProperties(CustomerManagementEnum.CONTRACT_SIGN_DATE, fieldAttrEntity);
                        fieldAttrEntity.setAttrType(FieldTypeEnum.DATETIME.getEsalias());
                        newFieldAttrEntityList.add(fieldAttrEntity);
                    }
                    if (opportunityAddDateExits) {
                        //机会创建时间
                        FieldAttrEntity fieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                        BeanUtil.copyProperties(CustomerManagementEnum.OPPORTUNITY_ADD_DATE, fieldAttrEntity);
                        fieldAttrEntity.setAttrType(FieldTypeEnum.DATETIME.getEsalias());
                        newFieldAttrEntityList.add(fieldAttrEntity);
                    }
                } else if (Objects.equals(XbbRefTypeEnum.CLUE.getCode(), businessType)) {
                    for (FieldAttrEntity fieldAttrEntity : fieldAttrEntityList) {
                        //新增的字段放在老的字段后面
                        newFieldAttrEntityList.add(fieldAttrEntity);
                        //如果该字段已经存在，不再需要添加该字段
                        String attr = fieldAttrEntity.getAttr();
                        if (Objects.equals(ClueEnum.BACK_NUM.getAttr(), attr)) {
                            clueBackNumExits = false;
                        } else if (Objects.equals(ClueEnum.PUBLIC_GROUP.getAttr(), attr)) {
                            cluePublicGroupExits = false;
                        }
                    }

                    if (!clueBackNumExits && !cluePublicGroupExits) {
                        isUpdate = false;
                    }
                    if (clueBackNumExits) {
                        //线索的退回次数字段
                        FieldAttrEntity fieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                        TempClueEnum.initBackNum(fieldAttrEntity);
                        BeanUtil.copyProperties(ClueEnum.BACK_NUM, fieldAttrEntity);
                        fieldAttrEntity.setAttrType(FieldTypeEnum.NUM.getEsalias());
                        fieldAttrEntity.setAccuracy(0);
                        newFieldAttrEntityList.add(fieldAttrEntity);
                    }
                    //旗舰版公司才刷该字段
                    if (cluePublicGroupExits) {
                        //线索的所属公海
                        FieldAttrEntity fieldAttrEntity = InitExplainsHelper.getNewFieldAttrEntity();
                        TempClueEnum.initPublicGroup(fieldAttrEntity);
                        BeanUtil.copyProperties(ClueEnum.PUBLIC_GROUP, fieldAttrEntity);
                        fieldAttrEntity.setAttrType(FieldTypeEnum.TEXT.getEsalias());
                        newFieldAttrEntityList.add(fieldAttrEntity);
                    }
                }

                if (isUpdate) {
                    entity.setExplains(JSONObject.toJSONString(newFieldAttrEntityList));
                    updateList.add(entity);
                }
            }
            if (CollectionsUtil.isNotEmpty(updateList)) {
                paasFormExplainModel.updateBatchExplains(updateList);
            }
        }
        LOGGER.warn("客户、线索表单解释新增字段完成，耗时{}", DateTimeUtil.getInt() - currentTime);

        String clueKey = PaasConstant.DEFAULT_DATA_CORPID + "_" + XbbRefTypeEnum.CLUE.getCode();
        paasRedisHelper.removeValue(RedisPrefixConstant.FIELD_EXPLANATION, clueKey);
        LOGGER.warn("删除线索的默认解释缓存");
        String customerKey = PaasConstant.DEFAULT_DATA_CORPID + "_" + XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
        paasRedisHelper.removeValue(RedisPrefixConstant.FIELD_EXPLANATION, customerKey);
        LOGGER.warn("删除客户的默认解释缓存");
        LOGGER.warn("脚本动作执行完成");
        return scriptVO;
    }

    @Override
    public ScriptVO removePublicPoolField(AllScriptDTO allScriptDTO) throws XbbException {
        LOGGER.warn("开始处理表单解释删除扩展字段");
        ScriptVO scriptVO = new ScriptVO();
        long currentTime = DateTimeUtil.getInt();
        List<String> corpidList = allScriptDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = paasFormExplainModel.getCorpidList();
            //corpidList.add("0");
        }
        Integer pageSize = allScriptDTO.getPageSize();
        if (Objects.isNull(pageSize)) {
            pageSize = 1000;
        }
        int totalCount = corpidList.size();
        int pageNum = totalCount % pageSize > 0 ? totalCount / pageSize + 1 : totalCount / pageSize;
        for (int currentPage = 1; currentPage <= pageNum; currentPage++) {
            int startIndex = (currentPage - 1) * pageSize;
            int endIndex = currentPage * pageSize;
            if (Objects.equals(currentPage, pageNum)) {
                endIndex = totalCount;
            }
            LOGGER.warn("开始执行{}——{}家公司，进度{}/{}", startIndex, endIndex, currentPage, pageNum);

            List<String> currentPageCorpidList = corpidList.subList(startIndex, endIndex);
            Map<String, Object> param = new HashMap<>();
            param.put("columns", "id,corpid,business_type,explains");
            param.put("corpidIn", currentPageCorpidList);
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("distributorMark", DistributorMarkEnum.OTHER.getCode());
            param.put("businessTypeIn", Lists.newArrayList(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), XbbRefTypeEnum.CLUE.getCode()));
            List<PaasFormExplainEntity> formExplainEntityList = paasFormExplainModel.findEntitys(param);
            if (CollectionsUtil.isEmpty(formExplainEntityList)) {
                continue;
            }
            List<PaasFormExplainEntity> updateList = new ArrayList<>(formExplainEntityList.size());
            for (PaasFormExplainEntity entity : formExplainEntityList) {
                Integer businessType = entity.getBusinessType();
                String explains = entity.getExplains();
                if (StringUtil.isEmpty(entity.getExplains())) {
                    continue;
                }
                List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(explains, FieldAttrEntity.class);
                if (CollectionsUtil.isEmpty(fieldAttrEntityList)) {
                    continue;
                }

                if (Objects.equals(XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), businessType)) {
                    fieldAttrEntityList.removeIf(item-> (Objects.equals(item.getAttr(),CustomerManagementEnum.PUBLIC_GROUP.getAttr()) ||
                            Objects.equals(item.getAttr(),CustomerManagementEnum.BACK_NUM.getAttr()) ||
                            Objects.equals(item.getAttr(),CustomerManagementEnum.CONTRACT_SIGN_DATE.getAttr()) ||
                            Objects.equals(item.getAttr(),CustomerManagementEnum.OPPORTUNITY_ADD_DATE.getAttr()) ));
                } else {
                    fieldAttrEntityList.removeIf(item-> (Objects.equals(item.getAttr(),ClueEnum.PUBLIC_GROUP.getAttr()) ||
                            Objects.equals(item.getAttr(),ClueEnum.BACK_NUM.getAttr()) ));
                }
                entity.setExplains(JSONObject.toJSONString(fieldAttrEntityList));
                updateList.add(entity);
            }
            if (CollectionsUtil.isNotEmpty(updateList)) {
                paasFormExplainModel.updateBatchExplains(updateList);
            }
        }

        LOGGER.warn("客户、线索表单解释删除新增字段完成，耗时{}", DateTimeUtil.getInt() - currentTime);
        String clueKey = PaasConstant.DEFAULT_DATA_CORPID + "_" + XbbRefTypeEnum.CLUE.getCode();
        paasRedisHelper.removeValue(RedisPrefixConstant.FIELD_EXPLANATION, clueKey);
        LOGGER.warn("删除线索的默认解释缓存");
        String customerKey = PaasConstant.DEFAULT_DATA_CORPID + "_" + XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode();
        paasRedisHelper.removeValue(RedisPrefixConstant.FIELD_EXPLANATION, customerKey);
        LOGGER.warn("删除客户的默认解释缓存");

        LOGGER.warn("删除扩展字段脚本动作执行完成");
        return scriptVO;
    }


    @Override
    public ScriptVO repairPerformanceData(RepairContractPerformanceDataDTO performanceDataDTO) throws XbbException {
        //
        LOGGER.warn("开始处理合同业绩分配脏数据");
        ScriptVO scriptVO = new ScriptVO();
        long currentTime = DateTimeUtil.getInt();
        List<String> corpidList = performanceDataDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            scriptVO.setMsg("无要刷的公司");
            return scriptVO;
        }

        Integer curCount = 1;
        int totalCount = corpidList.size();

        for (String corpid : corpidList) {
            LOGGER.warn("开始执行{}——{}家公司，进度{}/{}", totalCount, curCount, curCount, totalCount);
            // 获取是否有脏数据
            List<Long> contractIds = contractPerformanceModel.getDirtyDataContractIds(corpid);
            if (CollectionsUtil.isEmpty(contractIds)) {
                continue;
            }
            // 获取合同的业绩分配
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(StringConstant.CORPID, corpid);
            param.put("delIn", Arrays.asList(DelEnum.NORMAL.getDel(), DelEnum.APPROVE_STATUS.getDel()));
            param.put("contractIdIn", contractIds);
            int contractPerformanceCount = contractPerformanceModel.getEntitysCount(param);
            // 分类请求处理
            int pageSize = 1000;
            int totalPage = (contractPerformanceCount % pageSize == 0) ? (contractPerformanceCount / pageSize) : (contractPerformanceCount / pageSize) + 1;
            int lastPageSize = (contractPerformanceCount % pageSize == 0) ? pageSize : (contractPerformanceCount % pageSize);
            List<ContractPerformanceEntity> allList = new ArrayList<>();
            for ( int page = 0; page < totalPage; page++ ) {
                if (page == totalPage - 1) {
                    param.put("pageNum", lastPageSize);
                } else {
                    param.put("pageNum", pageSize);
                }
                param.put("start", page * pageSize);
                List<ContractPerformanceEntity> list = contractPerformanceModel.findEntitys(param);
                if (CollectionsUtil.isNotEmpty(list)) {
                    allList.addAll(list);
                }
            }

            // 业绩分配del状态map
            Map<Long, Set<Integer>> performanceDelMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            // 需要查询合同状态的contractIds
            Set<Long> queryContractIdSet = new HashSet<>();
            // 业绩分配分组
            Map<Long, List<ContractPerformanceEntity>> performanceMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (ContractPerformanceEntity item : allList) {
                List<ContractPerformanceEntity> groupList = performanceMap.getOrDefault(item.getContractId(), new ArrayList<>());
                groupList.add(item);
                performanceMap.put(item.getContractId(), groupList);

                Set<Integer> delSet = performanceDelMap.getOrDefault(item.getContractId(), new HashSet<>());
                delSet.add(item.getDel());
                // 需要查询合同状态的contractIds
                if (delSet.size() == BasicConstant.TWO) {
                    queryContractIdSet.add(item.getContractId());
                }
            }


            // 删除状态不正常数据
            Map<Long, List<Long>> deleteListMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);

            // 查询合同状态
            if (CollectionsUtil.isNotEmpty(queryContractIdSet)) {
                Map<String, Object> contractParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                contractParam.put(StringConstant.CORPID, corpid);
                contractParam.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
                contractParam.put("idIn", new ArrayList<>(queryContractIdSet));
                contractParam.put("columns", "id, flow_status");
                List<ContractEntityExt> contractList = contractModel.findEntitysWithoutSub(contractParam);

                for (ContractEntityExt entityExt : contractList) {
                    Long contractId = entityExt.getId();
                    Integer flowStatus = entityExt.getFlowStatus();

                    List<ContractPerformanceEntity> groupList = performanceMap.get(contractId);
                    Iterator<ContractPerformanceEntity> iterator = groupList.iterator();
                    while (iterator.hasNext()) {
                        ContractPerformanceEntity performanceEntity = iterator.next();
                        if (Objects.equals(flowStatus, performanceEntity.getDel())) {
                            continue;
                        }

                        List<Long> deleteList = deleteListMap.getOrDefault(contractId, new ArrayList<>());
                        deleteList.add(performanceEntity.getId());
                        deleteListMap.put(contractId, deleteList);

                        iterator.remove();
                    }
                }
            }

            // 删除重复员人数据
            Set<String> userIdSet = new HashSet<>();
            for (Map.Entry<Long, List<ContractPerformanceEntity>> entry : performanceMap.entrySet()) {
                Long contractId = entry.getKey();
                List<ContractPerformanceEntity> groupList = entry.getValue();
                userIdSet.clear();

                Iterator<ContractPerformanceEntity> iterator = groupList.iterator();
                while (iterator.hasNext()) {
                    ContractPerformanceEntity performanceEntity = iterator.next();
                    if (!userIdSet.contains(performanceEntity.getUserId())) {
                        userIdSet.add(performanceEntity.getUserId());
                        continue;
                    }
                    List<Long> deleteList = deleteListMap.getOrDefault(contractId, new ArrayList<>());
                    deleteList.add(performanceEntity.getId());
                    deleteListMap.put(contractId, deleteList);

                    iterator.remove();
                }
            }

            List<ContractPerformanceEntity> updateList = new ArrayList<>();

            // 业绩分配等新分配
            for (Map.Entry<Long, List<ContractPerformanceEntity>> entry : performanceMap.entrySet()) {
                List<ContractPerformanceEntity> groupList = entry.getValue();

                double sumRate = 0d;
                for(ContractPerformanceEntity performance : groupList){
                    sumRate = Arith.add(sumRate, performance.getRate());
                }
                if (Arith.sub(sumRate, BasicConstant.HUNDRED_PERCENT) <= ConfigConstant.amountAccuracy) {
                    continue;
                }
                // 重新分配规则现只有一种
                updateList.addAll(recalculatePerformance(groupList, entry.getKey(), deleteListMap));
            }

            if (!deleteListMap.isEmpty()) {
                for (Map.Entry<Long, List<Long>> entry : deleteListMap.entrySet()) {
                    Long contractId = entry.getKey();
                    List<Long> ids = entry.getValue();
                    try {
                        contractPerformanceModel.deleteBatch(ids, corpid, contractId);
                    } catch (XbbException e) {
                        LOGGER.error("删除失败！", e);
                    }
                }
            }
            if (CollectionsUtil.isNotEmpty(updateList)) {
                try {
                    contractPerformanceModel.updateBatch(updateList, corpid);
                } catch (XbbException e) {
                    LOGGER.error("更新合同业绩分配失败", e);
                }
            }
        }

        LOGGER.warn("合同业绩分配脏数据更新完成，耗时{}", DateTimeUtil.getInt() - currentTime);
        return scriptVO;

    }

    @Override
    public ScriptVO repairContractData(RepairContractPerformanceDataDTO performanceDataDTO) throws XbbException {
        LOGGER.warn("开始处理合同订单脏数据");
        ScriptVO scriptVO = new ScriptVO();
        List<String> corpidList = performanceDataDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            scriptVO.setMsg("无要刷的公司");
            return scriptVO;
        }
        String corpid = corpidList.get(0);
        Map<String, Object> param = new HashMap<>(4);
        param.put(StringConstant.COLUMNS, "id, data");
        param.put(StringConstant.CORPID, corpid);
        param.put(StringConstant.FORM_ID, 3238604);
//        param.put(StringConstant.FORM_ID, 36486);
        param.put("idGte", 0);
        param.put(StringConstant.ORDER_BY, "id asc");
        param.put(StringConstant.PAGE_SIZE, 1000);
        List<ContractEntityExt> contractEntityExtList = contractModel.findEntitys(param);
        boolean flag = true;
        int page =1;
        while (flag) {
            if (contractEntityExtList.size() < 1000) {
                flag = false;
            }
            // text_25
            // text_16
            // text_17
            if (CollectionsUtil.isNotEmpty(contractEntityExtList)) {
                LOGGER.warn("处理进度：当前处理第" + page + "页，每页"+ contractEntityExtList.size() +"条");
                page++;
                List<UpdateDataEntity> updateDataList = new ArrayList<>();
                for (ContractEntityExt contractEntityExt : contractEntityExtList) {
                    try {
                        String fixField1 = contractEntityExt.getData().getString("text_16");
                        String fixField2 = contractEntityExt.getData().getString("text_17");
                        String fixField3 = contractEntityExt.getData().getString("text_25");
                        boolean fixFlag = false;
                        JSONObject jsonObject = new JSONObject();
                        if (StringUtil.isNotEmpty(fixField1) && Objects.equals(fixField1.charAt(0), '[') && Objects.equals(fixField1.charAt(fixField1.length()-1), ']')) {
                            if (fixField1.length() > 2) {
                                jsonObject.put("text_16", fixField1.substring(2, fixField1.length() - 2));
                            } else {
                                jsonObject.put("text_16", "");
                            }
                            fixFlag = true;
                        }
                        if (StringUtil.isNotEmpty(fixField2) && Objects.equals(fixField2.charAt(0), '[') && Objects.equals(fixField2.charAt(fixField2.length()-1), ']')) {
                            if (fixField2.length() > 2) {
                                jsonObject.put("text_17", fixField2.substring(2, fixField2.length() - 2));
                            } else {
                                jsonObject.put("text_17", "");
                            }
                            fixFlag = true;
                        }
                        if (StringUtil.isNotEmpty(fixField3) && Objects.equals(fixField3.charAt(0), '[') && Objects.equals(fixField3.charAt(fixField3.length()-1), ']')) {
                            if (fixField3.length() > 2) {
                                jsonObject.put("text_25", fixField3.substring(2, fixField3.length() - 2));
                            } else {
                                jsonObject.put("text_25", "");
                            }
                            fixFlag = true;
                        }
                        if (fixFlag) {
                            UpdateDataEntity updateData = ExplainUtil.getUpdateData(contractEntityExt.getId(), jsonObject, corpid);
                            updateDataList.add(updateData);
                        }
                    } catch (Exception e) {
                        LOGGER.error("修复合同表单数据失败:ID {}", contractEntityExt.getId());
                    }
                }
                if (!updateDataList.isEmpty()) {
                    contractModel.updateBatch(updateDataList, corpid, WriteRequest.RefreshPolicy.NONE);
                }
                param.put("idGte", contractEntityExtList.get(contractEntityExtList.size()-1).getId());
                if (flag) {
                    contractEntityExtList = contractModel.findEntitys(param);
                }
            }
        }
        LOGGER.warn("处理合同订单脏数据结束");
        return scriptVO;
    }

    /**
     *
     * @Description: 同步应收款团队为对应的合同的团队
     * @param syncPaymentUserDTO
     * @return: com.xbongbong.pro.script.pojo.vo.ScriptVO
     * @Author: shen.yang
     * @Date: 2022/7/25  10:47
    */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ScriptVO syncPaymentUser(SyncPaymentUserDTO syncPaymentUserDTO) throws XbbException {
        long timeStart = DateTimeUtil.getInt();
        ScriptVO scriptVO = new ScriptVO();
        List<String> corpidList = syncPaymentUserDTO.getCorpidList();
        log.warn("----------syncPaymentUser start 开始执行应收款团队数据修复脚本----------");
        for (String corpid : corpidList) {
            log.warn("当前公司id:" + corpid);
            // 模拟分页
            Integer start = 0;
            //每次查询500条
            Integer pageNum = 500;
            HashMap<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put(ParameterConstant.CORPID, corpid);
            params.put(ParameterConstant.DEL, DelEnum.NORMAL);
            int paymentCount = paymentModel.getEntitysCount(params);
            //页数，用于记录进度
            int page = 1;
            for(Long idGte = 0L;start <= paymentCount; start = start + pageNum, page++){
                params.clear();
                params.put(ParameterConstant.CORPID, corpid);
                params.put(ParameterConstant.DEL, DelEnum.NORMAL);
                params.put(ParameterConstant.START, start);
                params.put(ParameterConstant.PAGE_NUM, pageNum);
                params.put(ParameterConstant.ORDER_BY_STR, "id asc");
                params.put("idGte", idGte);
                log.warn("处理进度：当前处理第" + page + "页，每页"+ pageNum +"条，tb_saas_payment.id = " + idGte);
                List<PaymentEntityExt> paymentEntityExtList = paymentModel.findEntitys(params);
                if(CollectionUtils.isEmpty(paymentEntityExtList)){
                    continue;
                }
                idGte = paymentEntityExtList.get(paymentEntityExtList.size() - 1).getId();

                Set<Long> paymentIdSet = paymentEntityExtList.stream().map(PaymentEntityExt::getId).collect(Collectors.toSet());
                params.clear();
                params.put(ParameterConstant.CORPID, corpid);
                params.put(ParameterConstant.DEL, DelEnum.NORMAL);
                params.put(ParameterConstant.DATA_ID_IN, paymentIdSet);
                params.put(ParameterConstant.IS_MAIN, Constant.ONE);
                List<PaymentUserEntity> paymentOwnerList = paymentUserModel.findAllEntitys(params);
                Set<Long> haveOwner = new HashSet<>();
                if(CollectionUtils.isNotEmpty(paymentOwnerList)){
                    //记录负责人不为空的应收款单据
                    haveOwner = paymentOwnerList.stream().map(PaymentUserEntity :: getDataId).collect(Collectors.toSet());
                }
                //paymentId -> contractId  应收款作为key是唯一，但是合同不一定
                Map<Long, Long> relationshipMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                for (PaymentEntityExt paymentEntity : paymentEntityExtList) {
                    JSONObject data = paymentEntity.getData();
                    long contractId = Long.parseLong(data.get(PaymentEnum.CONTRACT.getAttr()).toString());
                    relationshipMap.put(paymentEntity.getId(), contractId);
                }
                params.clear();
                params.put(ParameterConstant.CORPID, corpid);
                params.put(ParameterConstant.DEL, DelEnum.NORMAL);
                params.put(ParameterConstant.DATA_ID_IN, new HashSet<>(relationshipMap.values()));
                //查询合同团队数据
                List<ContractUserEntity> allUserList = contractUserModel.findEntitys(params);
                if(CollectionUtils.isEmpty(allUserList)){
                    continue;
                }
                Map<Long, List<ContractUserEntity>> contractUserMap = allUserList.stream().collect(Collectors.toMap(ContractUserEntity::getDataId, Collections::singletonList, (v1, v2) -> {
                    List<ContractUserEntity> result = new ArrayList<>();
                    result.addAll(v1);
                    result.addAll(v2);
                    return result;
                }));
                List<PaymentUserEntity> paymentUserList = new ArrayList<>();
                for (PaymentEntityExt paymentEntityExt : paymentEntityExtList) {
                    if(haveOwner.contains(paymentEntityExt.getId())){
                        //负责人团队不为空的不用同步
                        continue;
                    }
                    List<ContractUserEntity> contractUserList = contractUserMap.get(relationshipMap.get(paymentEntityExt.getId()));
                    if(CollectionUtils.isEmpty(contractUserList)){
                        continue;
                    }
                    List<PaymentUserEntity> paymentUserEntities = formatPaymentUser(contractUserList, paymentEntityExt);
                    paymentUserList.addAll(paymentUserEntities);
                }
                if(CollectionUtils.isNotEmpty(paymentUserList)){
                    //删除原应收款团队，防止有重复数据
                    paymentUserModel.disbandedTeamByDataId(corpid, paymentUserList.stream().map(PaymentUserEntity::getDataId).collect(Collectors.toList()));
                    paymentUserModel.insertBatch(paymentUserList);
                }
            }
        }
        log.warn("应收款团队数据修复脚本执行完毕-----------time consume syncPaymentUser:" + (DateTimeUtil.getInt() - timeStart));
        return scriptVO;
    }

    @Override
    public ScriptVO addCompetitor(AllScriptDTO allScriptDTO) throws XbbException {
        LOGGER.warn("开始机会表单解释刷上关联竞争对手、赢单竞品字段");
        ScriptVO scriptVO = new ScriptVO();
        long currentTime = DateTimeUtil.getInt();
        List<String> corpidList = allScriptDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = paasFormExplainModel.getCorpidList();
            corpidList.add("0");
        }
        Integer pageSize = allScriptDTO.getPageSize();
        if (Objects.isNull(pageSize)) {
            pageSize = 1000;
        }
        int totalCount = corpidList.size();
        int pageNum = totalCount % pageSize > 0 ? totalCount / pageSize + 1 : totalCount / pageSize;
        for (int currentPage = 1; currentPage <= pageNum; currentPage++) {
            int startIndex = (currentPage - 1) * pageSize;
            int endIndex = currentPage * pageSize;
            if (Objects.equals(currentPage, pageNum)) {
                endIndex = totalCount;
            }
            LOGGER.warn("开始执行{}——{}家公司，进度{}/{}", startIndex, endIndex, currentPage, pageNum);

            List<String> currentPageCorpidList = corpidList.subList(startIndex, endIndex);
            Map<String, Object> param = new HashMap<>();
            param.put("columns", "id,corpid,business_type,explains");
            param.put("corpidIn", currentPageCorpidList);
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("distributorMark", DistributorMarkEnum.OTHER.getCode());
            param.put("businessType", XbbRefTypeEnum.SALES_OPPORTUNITY.getCode());
            List<PaasFormExplainEntity> formExplainEntityList = paasFormExplainModel.findEntitys(param);
            if (CollectionsUtil.isEmpty(formExplainEntityList)) {
                continue;
            }
            List<PaasFormExplainEntity> updateList = new ArrayList<>(formExplainEntityList.size());
            for (PaasFormExplainEntity entity : formExplainEntityList) {
                String corpid = entity.getCorpid();
                Boolean isUltimate = false;
                Integer feeType = 1;
                if(!"0".equals(corpid)){
                    try {
                        feeType = packageHelp.getFeeType(corpid);
                    }catch (Exception e){
                        continue;
                    }
                }
                if (Objects.equals(feeType, PackageTypeEnum.ULTIMATE.getType())){
                    isUltimate = true;
                }
                Integer businessType = entity.getBusinessType();
                String explains = entity.getExplains();
                if (StringUtil.isEmpty(entity.getExplains())) {
                    continue;
                }
                List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(explains, FieldAttrEntity.class);
                if (CollectionsUtil.isEmpty(fieldAttrEntityList)) {
                    continue;
                }
                List<FieldAttrEntity> newFieldAttrEntityList = new ArrayList<>(fieldAttrEntityList.size());
                // 是否有关联竞争对手字段
                boolean linkCompetitorBool  = true;
                // 是否有赢单竞品字段
                boolean winCompetitorBool  = true;
                // 是否有赢单竞品字段
                boolean linkCompetitorLinkTextBool  = true;
                // 是否有赢单竞品字段
                boolean winCompetitorLinkTextBool  = true;
                if (Objects.equals(XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), businessType)) {
                    for (int i = 0; i < fieldAttrEntityList.size(); i++) {
                        FieldAttrEntity fieldAttrEntity = fieldAttrEntityList.get(i);
                        String attr = fieldAttrEntity.getAttr();

                        // 刷错了，强制刷，就去掉注释
                       /*if (Objects.equals(SalesOpportunityEnum.LINK_COMPETITOR.getAttr(), attr)) {
                            continue;
                        }
                        if (Objects.equals(SalesOpportunityEnum.WIN_COMPETITOR.getAttr(), attr)) {
                            continue;
                        }
                        if (Objects.equals(SalesOpportunityEnum.LINK_COMPETITOR_LINK_TEXT.getAttr(), attr)) {
                            continue;
                        }
                        if (Objects.equals(SalesOpportunityEnum.WIN_COMPETITOR_LINK_TEXT.getAttr(), attr)) {
                            continue;
                        }*/
                        newFieldAttrEntityList.add(fieldAttrEntity);
                        if (Objects.equals(SalesOpportunityEnum.LINK_COMPETITOR.getAttr(), attr)) {
                            linkCompetitorBool = false;
                        }
                        if (Objects.equals(SalesOpportunityEnum.WIN_COMPETITOR.getAttr(), attr)) {
                            winCompetitorBool = false;
                        }
                        if (Objects.equals(SalesOpportunityEnum.LINK_COMPETITOR_LINK_TEXT.getAttr(), attr)) {
                            linkCompetitorLinkTextBool = false;
                        }
                        if (Objects.equals(SalesOpportunityEnum.WIN_COMPETITOR_LINK_TEXT.getAttr(), attr)) {
                            winCompetitorLinkTextBool = false;
                        }
                    }
                    if (linkCompetitorBool){
                        //添加关联竞争对手字段
                        FieldAttrEntity linkCompetitor = InitExplainsHelper.getNewFieldAttrEntity();
                        BeanUtil.copyProperties(SalesOpportunityEnum.LINK_COMPETITOR, linkCompetitor);
                        linkCompetitor.setAttrNameEn(SalesOpportunityEnum.LINK_COMPETITOR.getAttrName());
                        linkCompetitor.setDefaultName(SalesOpportunityEnum.LINK_COMPETITOR.getAttrName());
                        linkCompetitor.setEditable(0);
                        linkCompetitor.setAttrType("text");
                        linkCompetitor.setIsRedundant(0);
                        TempSalesOpportunityEnum.initLinkCompetitor(linkCompetitor);
                        linkCompetitor.setIsOpen(0);
                        if(isUltimate){
                            linkCompetitor.setIsOpen(1);
                        }
                        newFieldAttrEntityList.add(linkCompetitor);
                    }
                    if (winCompetitorBool){
                        //添加关联竞争对手字段
                        FieldAttrEntity winCompetitor = InitExplainsHelper.getNewFieldAttrEntity();
                        BeanUtil.copyProperties(SalesOpportunityEnum.WIN_COMPETITOR, winCompetitor);
                        winCompetitor.setAttrNameEn(SalesOpportunityEnum.WIN_COMPETITOR.getAttrName());
                        winCompetitor.setDefaultName(SalesOpportunityEnum.WIN_COMPETITOR.getAttrName());
                        winCompetitor.setEditable(0);
                        winCompetitor.setAttrType("text");
                        winCompetitor.setIsRedundant(0);
                        TempSalesOpportunityEnum.initWinCompetitor(winCompetitor);
                        winCompetitor.setIsOpen(0);
                        if(isUltimate){
                            winCompetitor.setIsOpen(1);
                        }
                        newFieldAttrEntityList.add(winCompetitor);
                    }
                    if (linkCompetitorLinkTextBool){
                        //添加关联竞争对手字段隐藏字段
                        FieldAttrEntity linkCompetitorLinkText = InitExplainsHelper.getNewFieldAttrEntity();
                        BeanUtil.copyProperties(SalesOpportunityEnum.LINK_COMPETITOR_LINK_TEXT, linkCompetitorLinkText);
                        linkCompetitorLinkText.setAttrType("text");
                        newFieldAttrEntityList.add(linkCompetitorLinkText);
                    }
                    if (winCompetitorLinkTextBool){
                        //添加赢单竞品字段隐藏字段
                        FieldAttrEntity winCompetitorLinkText = InitExplainsHelper.getNewFieldAttrEntity();
                        winCompetitorLinkText.setAttrType("text");
                        BeanUtil.copyProperties(SalesOpportunityEnum.WIN_COMPETITOR_LINK_TEXT, winCompetitorLinkText);
                        newFieldAttrEntityList.add(winCompetitorLinkText);
                    }
                }
                if(linkCompetitorBool || winCompetitorBool || linkCompetitorLinkTextBool || winCompetitorLinkTextBool){
                    entity.setExplains(JSONObject.toJSONString(newFieldAttrEntityList));
                    updateList.add(entity);
                }
            }
            if (CollectionsUtil.isNotEmpty(updateList)) {
                paasFormExplainModel.updateBatchExplains(updateList);
            }
        }
        LOGGER.warn("机会表单解释新增竞争对手相关字段完成，耗时{}", DateTimeUtil.getInt() - currentTime);
        // 删除机会的默认解释缓存
        String key = "0" + "_" + XbbRefTypeEnum.SALES_OPPORTUNITY.getCode() + "_" + DistributorMarkEnum.OTHER.getCode();
        paasRedisHelper.removeValue(RedisPrefixConstant.FIELD_EXPLANATION, key);
        LOGGER.warn("删除机会的默认解释缓存");
        return scriptVO;
    }

    @Override
    public ScriptVO removeCompetitor(AllScriptDTO allScriptDTO) throws XbbException {
        LOGGER.warn("开始回滚机会表单解释刷上关联竞争对手、赢单竞品字段");
        ScriptVO scriptVO = new ScriptVO();
        long currentTime = DateTimeUtil.getInt();
        List<String> corpidList = allScriptDTO.getCorpidList();
        if (CollectionsUtil.isEmpty(corpidList)) {
            corpidList = paasFormExplainModel.getCorpidList();
            corpidList.add("0");
        }
        Integer pageSize = allScriptDTO.getPageSize();
        if (Objects.isNull(pageSize)) {
            pageSize = 1000;
        }
        int totalCount = corpidList.size();
        int pageNum = totalCount % pageSize > 0 ? totalCount / pageSize + 1 : totalCount / pageSize;
        for (int currentPage = 1; currentPage <= pageNum; currentPage++) {
            int startIndex = (currentPage - 1) * pageSize;
            int endIndex = currentPage * pageSize;
            if (Objects.equals(currentPage, pageNum)) {
                endIndex = totalCount;
            }
            LOGGER.warn("开始执行{}——{}家公司，进度{}/{}", startIndex, endIndex, currentPage, pageNum);
            List<String> currentPageCorpidList = corpidList.subList(startIndex, endIndex);
            Map<String, Object> param = new HashMap<>();
            param.put("columns", "id,corpid,business_type,explains");
            param.put("corpidIn", currentPageCorpidList);
            param.put("del", DelEnum.NORMAL.getDel());
            param.put("distributorMark", DistributorMarkEnum.OTHER.getCode());
            param.put("businessType", XbbRefTypeEnum.SALES_OPPORTUNITY.getCode());
            List<PaasFormExplainEntity> formExplainEntityList = paasFormExplainModel.findEntitys(param);
            if (CollectionsUtil.isEmpty(formExplainEntityList)) {
                continue;
            }
            List<PaasFormExplainEntity> updateList = new ArrayList<>(formExplainEntityList.size());
            for (PaasFormExplainEntity entity : formExplainEntityList) {
                Integer businessType = entity.getBusinessType();
                String explains = entity.getExplains();
                if (StringUtil.isEmpty(entity.getExplains())) {
                    continue;
                }
                List<FieldAttrEntity> fieldAttrEntityList = JSONArray.parseArray(explains, FieldAttrEntity.class);
                if (CollectionsUtil.isEmpty(fieldAttrEntityList)) {
                    continue;
                }
                List<FieldAttrEntity> newFieldAttrEntityList = new ArrayList<>(fieldAttrEntityList.size());
                // 是否有关联竞争对手字段
                boolean needUpdateBool  = false;
                if (Objects.equals(XbbRefTypeEnum.SALES_OPPORTUNITY.getCode(), businessType)) {
                    for (int i = 0; i < fieldAttrEntityList.size(); i++) {
                        FieldAttrEntity fieldAttrEntity = fieldAttrEntityList.get(i);
                        String attr = fieldAttrEntity.getAttr();
                        if (Objects.equals(SalesOpportunityEnum.LINK_COMPETITOR.getAttr(), attr)) {
                            needUpdateBool  = true;
                            continue;
                        }
                        if (Objects.equals(SalesOpportunityEnum.WIN_COMPETITOR.getAttr(), attr)) {
                            needUpdateBool  = true;
                            continue;
                        }
                        if (Objects.equals(SalesOpportunityEnum.LINK_COMPETITOR_LINK_TEXT.getAttr(), attr)) {
                            needUpdateBool  = true;
                            continue;
                        }
                        if (Objects.equals(SalesOpportunityEnum.WIN_COMPETITOR_LINK_TEXT.getAttr(), attr)) {
                            needUpdateBool  = true;
                            continue;
                        }
                        newFieldAttrEntityList.add(fieldAttrEntity);
                    }
                }
                if(needUpdateBool){
                    entity.setExplains(JSONObject.toJSONString(newFieldAttrEntityList));
                    updateList.add(entity);
                }
            }
            if (CollectionsUtil.isNotEmpty(updateList)) {
                paasFormExplainModel.updateBatchExplains(updateList);
            }
        }
        LOGGER.warn("回滚机会表单解释新增竞争对手相关字段完成，耗时{}", DateTimeUtil.getInt() - currentTime);
        // 删除机会的默认解释缓存
        String key = "0" + "_" + XbbRefTypeEnum.SALES_OPPORTUNITY.getCode() + "_" + DistributorMarkEnum.OTHER.getCode();
        paasRedisHelper.removeValue(RedisPrefixConstant.FIELD_EXPLANATION, key);
        LOGGER.warn("删除机会的默认解释缓存");
        return scriptVO;
    }

    /**
     *
     * @Description: 将合同团队数据封装成应收款团队
     * @param contractUserList
     * @return: java.util.List<com.xbongbong.saas.domain.entity.PaymentUserEntity>
     * @Author: shen.yang
     * @Date: 2022/7/25  14:16
    */
    private List<PaymentUserEntity> formatPaymentUser(List<ContractUserEntity> contractUserList, PaymentEntityExt paymentEntityExt){
        List<PaymentUserEntity> paymentUserList = new ArrayList<>();
        for (ContractUserEntity contractUserEntity : contractUserList) {
            PaymentUserEntity paymentUserEntity = new PaymentUserEntity();
            paymentUserEntity.setContractId(contractUserEntity.getDataId());
            paymentUserEntity.setCustomerId(contractUserEntity.getCustomerId());
            //refType暂时不传，不知道干嘛用的
            //paymentUserEntity.setRefType();
            paymentUserEntity.setCorpid(paymentEntityExt.getCorpid());
            paymentUserEntity.setUserId(contractUserEntity.getUserId());
            paymentUserEntity.setUserName(contractUserEntity.getUserName());
            paymentUserEntity.setUserAvatar(contractUserEntity.getUserAvatar());
            paymentUserEntity.setDataId(paymentEntityExt.getId());
            paymentUserEntity.setIsMain(contractUserEntity.getIsMain());
            paymentUserEntity.setDel(contractUserEntity.getDel());
            paymentUserEntity.setAddTime(contractUserEntity.getAddTime());
            paymentUserEntity.setUpdateTime(contractUserEntity.getUpdateTime());
            paymentUserEntity.setFormPermission(contractUserEntity.getFormPermission());
            paymentUserList.add(paymentUserEntity);
        }
        return paymentUserList;
    }
    /***
     * 分配规则1: 平均分给所有人
     *
     * @param oldList
     * @throws
     * @return
     * @author hongxiao
     * @date 2022-06-07 16:24
     * @since
     * @version
     */
    private List<ContractPerformanceEntity> recalculatePerformance(List<ContractPerformanceEntity> oldList, Long contractId, Map<Long, List<Long>> deleteListMap) {
        List<ContractPerformanceEntity> updateList = new ArrayList<>();
        // 没有需要分配的数据
        if (CollectionsUtil.isEmpty(oldList)) {
            return updateList;
        }
        // 超过100人，只分给第一个人
        if (oldList.size() > 100) {
            ContractPerformanceEntity entity = oldList.get(0);
            entity.setRate(100D);
            updateList.add(entity);

            // 其他人删除
            List<Long> deleteIdList = deleteListMap.getOrDefault(contractId, new ArrayList<>());
            List<ContractPerformanceEntity> deleteList = oldList.subList(1, oldList.size());
            deleteList.forEach(item -> deleteIdList.add(item.getId()));
            deleteListMap.put(contractId, deleteIdList);

            return updateList;
        }

        int remainder = 100 % oldList.size();
        int rate = 100 / oldList.size();

        for (int i = 0; i < oldList.size(); i++) {
            ContractPerformanceEntity entity = oldList.get(i);
            entity.setRate((double) rate);
            if (i == 0) {
                entity.setRate((double) rate + (double) remainder);
            }
            updateList.add(entity);
        }

        return updateList;
    }

    /**
     *
     * @Description: 同步联系人团队为对应的客户的团队
     * @param syncContactUserDTO
     * @return: com.xbongbong.pro.script.pojo.vo.ScriptVO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ScriptVO syncContactUser(SyncContactUserDTO syncContactUserDTO) throws XbbException {
        long timeStart = DateTimeUtil.getInt();
        ScriptVO scriptVO = new ScriptVO();
        List<String> corpidList = syncContactUserDTO.getCorpidList();
        log.warn("----------syncContactUser start 开始执行联系人团队数据修复脚本----------");
        for (String corpid : corpidList) {
            log.warn("当前公司id:" + corpid);
            //模拟分页
            //每次查询500条
            Integer pageNum = 500;
            HashMap<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            params.put(ParameterConstant.CORPID, corpid);
            params.put(ParameterConstant.DEL, DelEnum.NORMAL);
            Long idGte = 0L;
            while(true){
                params.clear();
                params.put(ParameterConstant.CORPID, corpid);
                params.put(ParameterConstant.DEL, DelEnum.NORMAL);
                params.put(ParameterConstant.PAGE_SIZE, pageNum);
                params.put(ParameterConstant.ORDER_BY_STR, "id asc");
                params.put("idGte", idGte);
                log.warn("处理进度：已处理到tb_saas_contact.id = " + idGte);
                List<ContactEntityExt> contactEntityExtList = contactModel.findEntitys(params);
                if(CollectionUtils.isEmpty(contactEntityExtList)){
                    break;
                }
                idGte = contactEntityExtList.get(contactEntityExtList.size() - 1).getId();

                Map<Long, Long> relationshipMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                for (ContactEntityExt contactEntityExt : contactEntityExtList) {
                    JSONObject data = contactEntityExt.getData();
                    if (data.get(ContactEnum.CUSTOMER_NAME.getAttr()) == null){
                        continue;
                    }
                    long customerId;
                    try {
                        customerId = Long.parseLong(data.get(ContactEnum.CUSTOMER_NAME.getAttr()).toString());
                    } catch (Exception e){
                        log.warn("获取联系人客户失败,失败联系人id:" + contactEntityExt.getId());
                        continue;
                    }
                    relationshipMap.put(contactEntityExt.getId(), customerId);
                }
                params.clear();
                params.put(ParameterConstant.CORPID, corpid);
                params.put(ParameterConstant.DEL, DelEnum.NORMAL);
                params.put(ParameterConstant.DATA_ID_IN, new HashSet<>(relationshipMap.values()));
                //查询客户团队数据
                List<CustomerUserEntity> allUserList = customerUserModel.findEntitys(params);
                if(CollectionUtils.isEmpty(allUserList)){
                    continue;
                }
                Map<Long, List<CustomerUserEntity>> customerUserMap = allUserList.stream().collect(Collectors.toMap(CustomerUserEntity::getDataId, Collections::singletonList, (v1, v2) -> {
                    List<CustomerUserEntity> result = new ArrayList<>();
                    result.addAll(v1);
                    result.addAll(v2);
                    return result;
                }));
                List<ContactUserEntity> contactUserList = new ArrayList<>();
                for (ContactEntityExt contactEntityExt : contactEntityExtList) {
                    List<CustomerUserEntity> customerUserList = customerUserMap.get(relationshipMap.get(contactEntityExt.getId()));
                    if(CollectionUtils.isEmpty(customerUserList)){
                        continue;
                    }
                    List<ContactUserEntity> contactUserEntities = formatContactUser(customerUserList, contactEntityExt);
                    contactUserList.addAll(contactUserEntities);
                }
                if(CollectionUtils.isNotEmpty(contactUserList)){
                    //删除原联系人团队，防止有重复数据
                    contactUserModel.disbandedTeamByDataId(corpid, contactEntityExtList.stream().map(ContactEntityExt::getId).collect(Collectors.toList()));
                    contactUserModel.insertBatch(contactUserList, false);
                }
            }
        }
        log.warn("联系人团队数据修复脚本执行完毕-----------time consume syncContactUser:" + (DateTimeUtil.getInt() - timeStart));
        return scriptVO;
    }

    /**
     *
     * @Description: 将客户团队数据封装成联系人团队
     */
    private List<ContactUserEntity> formatContactUser(List<CustomerUserEntity> customerUserList, ContactEntityExt contactEntityExt){
        List<ContactUserEntity> contactUserList = new ArrayList<>();
        for (CustomerUserEntity customerUserEntity : customerUserList) {
            ContactUserEntity contactUserEntity = new ContactUserEntity();
            contactUserEntity.setCustomerId(customerUserEntity.getDataId());
            contactUserEntity.setCorpid(contactEntityExt.getCorpid());
            contactUserEntity.setUserId(customerUserEntity.getUserId());
            contactUserEntity.setUserName(customerUserEntity.getUserName());
            contactUserEntity.setUserAvatar(customerUserEntity.getUserAvatar());
            contactUserEntity.setDataId(contactEntityExt.getId());
            contactUserEntity.setIsMain(customerUserEntity.getIsMain());
            contactUserEntity.setDel(customerUserEntity.getDel());
            contactUserEntity.setAddTime(customerUserEntity.getAddTime());
            contactUserEntity.setUpdateTime(customerUserEntity.getUpdateTime());
            contactUserEntity.setFormPermission(customerUserEntity.getFormPermission());
            contactUserList.add(contactUserEntity);
        }
        return contactUserList;
    }

}
